Reactive templates
Add the template parameter to a tag to insert Grid expressions. Each expression participates in the normal dependency graph. Changing an input updates the resulting value without recompiling…
Reactive templates
Add the template parameter to a tag to insert Grid expressions. Each
expression participates in the normal dependency graph. Changing an input
updates the resulting value without recompiling the model.
input Customer = "Ada"
input Quantity = 2
input UnitPrice = 12
Greeting = <raw template>Hello {{Customer}}!</raw>
Order = <json template>
{"customer": {{Customer}}, "total": {{Quantity * UnitPrice}}}
</json>
raw(template)"Hello {{Customer}}" and triple-quoted tagged strings work too.
Ordinary quoted payloads decode Grid string escapes; blocks and triple quotes
preserve literal bytes. Existing literals without template keep their current
behavior. In particular, <raw>{{Customer}}</raw> remains verbatim text.
Executable Lua tags also use explicit template, with typed scalar operands:
<lua type="number" template>return {{Quantity}} * {{UnitPrice}}</lua>.
Lua needs no import in a runtime packaged with its engine. See
Executable language tags for boundary types and lifecycle.
Choose delimiters
Each format declares its delimiter defaults. Most built-ins use {{ and }};
js uses ${ and }. Imported formats declare defaults in package metadata.
Override either delimiter with a start or end attribute when needed:
Greeting = <raw template start="[[" end="]]">Hello [[Customer]]!</raw>
Both delimiters are fixed quoted strings of 1–64 UTF-8 bytes, without control
characters. They belong to this template only; they are not runtime cell
values. Unicode delimiters are supported. Doubling the opening delimiter
emits it literally: {{{{ emits {{, and [[[[ emits [[. The closing
delimiter has no special meaning outside a hole. Use distinctive delimiter
pairs that do not conflict with the literal's enclosing quote or closing tag.
A hole contains a normal Grid expression. Strings, comments, and balanced expression brackets protect delimiter text inside that expression. Empty or unterminated holes are compilation errors. Source formatting and syntax-tree inspection preserve the delimiter pair and never execute an extension package.
Values and text
The format determines what an insertion means:
| Format | Whole value or field | Inside text |
|---|---|---|
raw and textual tags |
Text conversion | Text conversion |
| JSON | Native value, including arrays and objects | Text within a quoted string |
| YAML and TOML | Native value in a scalar position | Text within a string |
| CSV and TSV | Native value in a complete data field | Text within a field |
| HTML, XHTML, XML, SVG | Text nodes and attribute values | Text conversion |
Static format structure is parsed during compilation. JSON object keys, table headers, markup tag names, and attribute names must be static. For a dynamic collection, insert an expression that produces that collection into a value slot. This version does not splice markup subtrees, add rows from source text, or accept holes in discarded comments. YAML aliases that duplicate a hole and XML document type declarations are rejected.
Summary = <json template>
{"count": {{Quantity}}, "label": "Hello {{Customer}}"}
</json>
Card = <html template>
<p title="{{Customer}}">Total: {{Quantity * UnitPrice}}</p>
</html>
Values are inserted into native structure. Serializers own JSON quoting and
markup escaping; a customer's name containing <, &, or quotes does not
become markup syntax. Formatting a complete document still costs time
proportional to its output size.
Additional formats
An explicitly imported extension literal can declare a separate template compiler. It receives static chunks and returns a bounded native construction plan; Grid retains and compiles the expressions. A constant parser alone does not supply template support. See Extension-defined literals.
Specialized representations need their own construction adapter. music,
jsx, date/datetime, exact numeric, point, bounding-box and polygon templates
currently report that no adapter is installed. When a
domain constructor is deliberately desired, use an explicit call with a raw
template, for example MUSIC_SCORE(<raw template>{{Notation}}</raw>); that
constructor retains its usual runtime cost.
Execution timing
Compilation recognizes delimiters, compiles each Grid expression, parses the static format, validates any extension plan, and lowers construction to normal native expressions. Runtime evaluation reads those dependencies and constructs the value through the single compiled formula evaluator. Structured documents use the existing typed-document carrier, whose materialization and transport cost scale with value size. It does not scan delimiters or invoke the template compiler on first access or on subsequent changes.
Compiled extension templates run without their template package. Recompilation requires that exact package again. Ordinary extension function calls inside a hole still have their own runtime dependency.