Skip to content

Search titles, headings, and documentation content.

↑↓ navigate Enter open Esc close

    Browse documentation
    On this page

    Runtime templates

    Runtime templates are the narrow exception to Sklair's runtime-free output. They exist for the rare instanc where markup must be created after page load. Good thing it is insanely simple.

    List template components at the root of sklair.json:

    {
      "templates": ["AudioTier"]
    }
    

    Then use the otherwise-empty component once in any document which needs it:

    <AudioTier></AudioTier>
    

    That invocation registers the template; it does not render a visible instance. Sklair writes one hidden template registry and /_sklair/runtime.mjs only for documents which require them.

    Rendering an instance

    import { renderTemplate } from "/_sklair/runtime.mjs"
    
    const badge = renderTemplate("AudioTier", {
      label: "Master",
      tier: "master",
      spec: "24-bit / 96 kHz",
    })
    
    target.append(badge)
    

    renderTemplate returns a fresh DocumentFragment. The name is trimmed and matched case-insensitively. An unregistered template is an error.

    Runtime bindings

    Template source uses the same spelling as compile-time bindings:

    <span sklair-if="available"
          sklair-attr-data-tier="tier"
          sklair-prop-hidden="hidden"
          sklair-class-featured="featured">
      <span sklair-text="label"></span>
    </span>
    

    Sklair rewrites these to generated data-sklair-* attributes inside the native template. Authors must never write that generated namespace themselves.

    sklair-if removes false subtrees. Text, attribute, property, and class bindings require their named value. Nullish attribute values remove the target attribute; property bindings assign the live DOM property.

    Bindings run once while cloning - there is NO REACTIVITY (yuck) or expression language.

    Runtime bodies

    A template may expose one <slot></slot>. Pass a Node, DocumentFragment, or iterable of nodes as the third argument:

    renderTemplate("Card", { title: "Album" }, artwork)
    

    Omitting the body removes the marker. Supplying a body to a template without a slot is an error. Strings are not treated as HTML.

    Registration rules

    Registration invocations cannot have attributes or children and may appear only once explicitly in one document or component source. Requirements reached transitively are deduplicated. Template definitions cannot contain compile-time Lua, their heads cannot contain runtime bindings, and a dependency beneath a template cannot contain dynamic compile-time Lua.