Skip to content

Template Engine ​

Grammar (EBNF) ​

variable = "{{", ws, path, [ws, "|", ws, format], [ws, "??", ws, string], ws, "}}" ;
path     = identifier, { ".", identifier | "[", integer, "]" } ;
format   = identifier, [":", formatArg] ;

Examples: {{name}}, {{customer.address.city}}, {{invoice.total | currency:ARS}}, {{createdAt | date:dd/MM/yyyy}}, {{missing ?? "Sin datos"}}

No JS execution; formatters are registered typed functions.

API ​

ts
const result = renderTemplate(document, data, {
  mode: "strict", locale: "es-AR", timezone: "America/Argentina/Buenos_Aires", missing: "error"
});
// → { document: materialized, diagnostics, usedVariables, unusedVariables }

Security ​

  • Own-property access only, blocks __proto__/prototype/constructor, max depth 10, max result length 10000, values become text nodes never HTML.

Repeat rows ​

ts
table.repeat = { path: "items", alias: "item", templateRowId: "tmpl" }
// Inside cell: {{item.name}} → cloned per collection element with new IDs

Handles empty collection (fallback row), limit 1000, header repeat on page split via layout.

See src/template/parser/parser.ts, resolver/resolver.ts, formatter/.

Zero runtime dependencies — TypeScript strict — MIT