Core Concepts
The TemplateEngine
TemplateEngine is the only entry point. Construct it with a template string and call Merge(object) to produce output.
var ngin = new TemplateEngine("Hello {Name}.");
string result = ngin.Merge(new { Name = "World" });Tag delimiters
Tags use single curly braces. The prefix determines tag behavior:
| Prefix | Tag type | Example |
|---|---|---|
| (none) | Simple bind | {Name} |
#if | Conditional block | {#if Condition}…{/if} |
#each | Iteration block | {#each Items}…{/each} |
#with | Scope-shift block | {#with Path}…{/with} |
> | Partial template | {>Partial} |
?var: | Variable declaration | {?var:name = value} |
?: | Variable reassignment | {?:name = value} |
: | Variable read | {:name} |
! | Comment | {! comment here } |
@ | Debug tag | {@ expr } |
Bracket escaping
Double any literal brace in the template: {{ → {, }} → }. An unmatched } outside a tag is a parse error.
Local scope and $
$ is the current local scope — the object passed to Merge at the root, the current item inside {#each}, or the target inside {#with}. Bare names resolve against local scope automatically, so $ is optional for property access:
new TemplateEngine("Hello {$.FirstName}").Merge(data);
// equivalent to:
new TemplateEngine("Hello {FirstName}").Merge(data);$ is mandatory when iterating scalars via {#each} (no property name to bind against). It is also a reserved character — it cannot appear in property names.
var result = new TemplateEngine("To: {#each Emails}{$};{/each}")
.Merge(new { Emails = new[] { "john@mail.com", "jane@mail.com" } });Expected output:
To: john@mail.com;jane@mail.com;Whitespace inside tags
Whitespace inside a tag is insignificant: {Address.City} and { Address.City } are equivalent. Whitespace inside string literal arguments is preserved exactly as quoted.
Falsy semantics
{#if}, {#each}, and {#with} evaluate the bound expression against a fixed falsy ruleset:
falsenull- numeric zero
- empty string
- empty collection
DBNull.Value
Everything else is truthy.
null or default value if you need the falsy path.Engine state
TemplateEngine is not thread-safe. Use one instance per thread or guard a shared instance externally.
| Member | Type | Default | Purpose |
|---|---|---|---|
TrimWhitespace | bool | false | Apply whitespace trimming to every eligible tag. See Whitespace Control. |
LambdaRepo | LambdaRepository | empty | Registry of named functions callable from any tag. See Lambda Expressions. |
MaxStack | const int | 64 | Maximum block + partial nesting depth. See Stack Depth Limit. |
Next steps
- Simple Tags — bind expressions and nested property access
- Conditionals and Iteration — block tags driven by truthy/falsy
- Variables — declare template-local state with explicit lifetimes
- Lambda Expressions — register functions callable from any tag