NURLNURL registrynurl-lang.org →

← template

template 0.1.0 API

main.nu

template — render a template from the command line.

template -f page.html -c ctx.json # render with a JSON context template -f page.html # empty context echo '{{ msg }}' | template -c ctx.json # template from stdin template -f page.html -c ctx.json -p views # partials dir for {% include %}

The context file must contain a JSON object; {% include 'name' %} resolves against --partials (every *.html in the dir, named by basename without the extension).

API

@ main → i


template.nu

template — an HTML template engine for NURL.

Jinja-flavoured syntax rendered against a stdlib Json context:

{{ user.name }} output, HTML-escaped by default {{ body | raw }} filters: raw / upper / lower / length / json {% if admin %} … {% elif x == 'y' %} … {% else %} … {% end %} {% for item in items %} {{ loop.index }}: {{ item.title }} {% end %} {% include 'partial' %} from a TplSet (tset_* below) {# comment #}

Expressions are a dotted path (user.name, rows.0.id, loop vars), a quoted string literal ('x' or "x"), a number, or true/false — optionally combined with == / != or prefixed with not. Inside a {% for %} body, loop.index (0-based), loop.first, loop.last and loop.length resolve from the innermost loop.

Missing keys render as empty and are falsy (mustache-style lenient); malformed tags are hard errors. Rendering is an interpreter over the source — a {% for %} body is re-scanned per item, so templates stay data, no AST to manage.

Surface: ( tpl_render src ctx ) → !String String one-shot render ( tset_new ) / ( tset_add t n s ) named-template set (enables include) ( tset_render t name ctx ) → !String String ( tpl_render_with t src ctx ) → !String String one-shot + includes ( tset_free t )

The error payload is an owned String: "template error at line L, col C: …". Known limits (v0.1): }}/%} inside a string literal ends the tag; error positions inside an included template are reported against the including template's source.

API

: TplSet

: TplSet {
    ( Vec String ) names
    ( Vec String ) srcs
}

@ tset_new → *TplSet

@ tset_add * TplSet t s name s tsrc → v

Register (or replace) a named template. Copies both arguments.

@ tset_has * TplSet t s name → b

@ tset_free * TplSet t → v

: TplR

: TplR {
    s src
    i len
    i pos
    i setp  // *TplSet as an integer; 0 = no set (include fails)
    i depth  // include nesting guard
    i tag_a  // {% elif %} expression span, handed to the if-handler
    i tag_b
    i e_end  // one-past-end of the last parsed primary expression
    b failed
    i err_pos
    String err
    String out
    String key  // scratch: NUL-terminated path segment / include name
    ( Vec Json ) ctxv  // [0] = root context (borrow)
    ( Vec String ) sc_names  // loop-variable scope stack (owned names)
    ( Vec Json ) sc_vals  // parallel values (borrows)
    ( Vec i ) lp_idx  // loop frames, innermost last
    ( Vec i ) lp_len
    i va_kind
    b va_bool
    f va_num
    b va_raw
    String va_str
    ( Vec Json ) va_node
    i vb_kind
    b vb_bool
    f vb_num
    String vb_str
    ( Vec Json ) vb_node
}

@ tpl_render s tsrc Json jctx → !String String

Render template source against a Json context. The error payload is an owned String ("template error at line L, col C: …").

@ tpl_render_with * TplSet t s tsrc Json jctx → !String String

Same, with a TplSet so {% include 'name' %} resolves.

@ tset_render * TplSet t s name Json jctx → !String String

Render a named member of the set.


loader.nu

loader — fill a TplSet from a directory of template files.

( tset_load_dir t dir ext ) loads every dir/*<ext> file (e.g. ext .html) into the set, named by its basename without the extension: views/index.htmlindex. Returns the number of templates loaded, or -1 when the directory glob fails. Individual unreadable files are skipped (counted out), not fatal.

Kept out of template.nu so the engine itself has no fs dependency.

API

@ tset_load_dir * TplSet t s dir s ext → i