Templates
Every placeholder pattern the engine recognizes — with examples.
Text boxes
Substitute values, format numbers/dates, fall back when missing, or swap in an image.
| Placeholder | Meaning |
|---|---|
{name} | Substitute the value as text |
{user.email} | Dot notation for nested objects: user.email → data.user.email |
{price|number|#,##0} | Type + format. Types: text / number / date |
{rate|number|0.00%} | Decimal pattern — 0.27 → 27.00% |
{date|date|yyyy-MM-dd} | Format follows Joda-Time tokens (yyyy, MM, dd, HH, mm) |
{date|date|yyyy-MM-dd|N/A} | Fourth field is a fallback when the value is missing |
{name||N/A} | Empty type/format with a fallback — used when value is null |
{$photoUrl} | Replace with an image from URL or base64 |
Example
Hello {customerName},
Your order total is {total|number|$#,##0.00}.
Issued on {issuedAt|date|yyyy-MM-dd|today}.{
"customerName": "Acme Corp",
"total": 35000.5,
"issuedAt": "2026-05-24"
}Hello Acme Corp,
Your order total is $35,000.50.
Issued on 2026-05-24.Slide notes
Slide-level constructs (conditional render, per-element repetition) go in the slide notes pane.
| Placeholder | Meaning |
|---|---|
{#user.isPaid} | Render the slide only when the JS expression is truthy (GraalJS) |
{#price > 1000} | Expressions can reference any data field — operators, comparisons, etc. |
{@items} | Repeat the slide per array element |
{@items|10} | Paginate — N elements per repeated slide |
Conditional slide
Put a JS expression in the slide notes. The slide is dropped from the output when the expression is falsy (evaluated via GraalJS).
{#user.isPaid}Repeating slide
Render the slide once per array element. Append |N to paginate N elements per output slide.
{@products|3}{name} — {price|number|$#,##0}Inside the loop body, placeholders refer to the current element's fields.
Tables
Loop table rows, slice ranges, summarize, or rebuild a table column-by-column.
| Placeholder | Meaning |
|---|---|
{@rows} | Repeat the row per array element |
{@rows.[10,20]} | Render only indexes 10–20 (inclusive) |
{=rows} | Start a summary (sum/avg) row over the looped data |
{column} | First cell of a row → repeat by column instead |
{/} | End-of-loop marker — required on the last cell of the loop row |
Row loop
Mark the first cell of the looping row with {@rows} and the last cell with {/}. Each array element produces one duplicated row.
{@rows}{/}Within the row, cells reference fields of each row object — e.g. {name}, {qty}, {unitPrice}.
Tips
- Placeholder names are case-sensitive. {name} ≠ {Name}.
- Nested object access: {user.email}. Array iteration uses {@array}; positional access ({arr[0]}) is not supported.
- When a value is null and no fallback is set, the placeholder stays as-is — easier to spot missing data.
- Image URLs must be HTTPS-fetchable. Base64 data: URIs are also accepted.
- Bind locally with the engine before shipping a new template — catches typos early.
locale=en