somni-template
A small, configurable templating engine built on top of somni-expr.
Templates are transpiled into a Somni program and executed: literal text is emitted verbatim,
while {{ expr }} interpolations, if/for conditions and loop iterables are evaluated by
somni-expr.
Features
- Configurable syntax. Interpolation delimiters and block-directive style are both
configurable. Block directives can be a delimiter pair (e.g.
{% ... %},/* ... */) or a line prefix (e.g.#,//). An optional text line prefix (e.g.//>) is stripped from matching lines so the remainder is emitted as text — useful when the template is also a valid program and conditional output must stay commented if run directly. Optional----fenced frontmatter at the start of a template may override the syntax passed toTemplate::compile(frontmatter wins for keys it sets). - Control flow.
if/else if/elseandfor <var> in <iterable>(with an optional<var>: <type>annotation), arbitrarily nestable. - Strongly typed output. Interpolation is string-only; convert other types explicitly
(a generic
strconversion is provided, more can be registered). - Errors point into the template, even for evaluation errors in the generated program.
Example
use ;
let tmpl = compile
.unwrap;
let mut env = new; // ships a default `str` conversion
env.value;
env.value;
let out = tmpl.render.unwrap;
assert_eq!;
Notes
- Interpolation must evaluate to a
string; use{{ str(x) }}(or a custom conversion) for other types. forneeds a host-provided iterable. The loop-variable type annotation is optional (for x in ...); when omitted it is inferred from how the variable is used, but it can still be given explicitly (for x: int in ...).- Iterables registered with [
Iter] are single-pass. To re-iterate a source (e.g. an inner loop nested in an outer loop), register a host function that returns a fresh iterator and call it in the loop header (#for x: int in items()).
License
Licensed under either of Apache-2.0 or MIT, at your option.