Template API Reference

Template engine with variable interpolation, conditionals, loops, filters, and partials

Import

U std/template

Overview

The template module provides a lightweight template engine supporting:

  • Variable interpolation {{ var }}
  • Filters {{ var | upper }}
  • Conditionals {% if condition %}...{% endif %}
  • Loops {% for item in list %}...{% endfor %}
  • Partials {% include "name" %}
  • HTML escaping and security
  • Compiled template caching

Constants

Node Types

ConstantValueDescription
NODE_TEXT0Raw text node
NODE_VAR1Variable interpolation {{ var }}
NODE_IF2Conditional block {% if cond %}
NODE_FOR3Loop block {% for item in list %}
NODE_INCLUDE4Include partial {% include "name" %}
NODE_FILTER5Variable with filter {{ var | filter }}

Filter Types

ConstantValueDescription
FILTER_NONE0No filter applied
FILTER_UPPER1Convert to uppercase
FILTER_LOWER2Convert to lowercase
FILTER_ESCAPE3HTML escape
FILTER_TRIM4Trim whitespace
FILTER_LENGTH5Get string length

Value Types

ConstantValueDescription
VAL_STR0String value
VAL_INT1Integer value
VAL_LIST2Array of string pointers

Buffer Sizes

ConstantValueDescription
TPL_MAX_NODES256Maximum template nodes
TPL_MAX_VARS64Maximum context variables
TPL_BUFFER_SIZE65536Render buffer size (64KB)
TPL_KEY_SIZE128Maximum key length
TPL_VAL_SIZE4096Maximum value length

Structs

TemplateCtx

Template context stores key-value pairs for variable interpolation.

S TemplateCtx {
    handle: i64    # Opaque pointer to C runtime context
}

Methods

MethodSignatureDescription
newF new() -> TemplateCtxCreate a new template context
set_strF set_str(&self, key: str, value: str) -> TemplateCtxSet a string variable (chainable)
set_intF set_int(&self, key: str, value: i64) -> TemplateCtxSet an integer variable (chainable)
getF get(&self, key: str) -> strGet a variable value (returns "" if not found)
is_truthyF is_truthy(&self, key: str) -> i64Check if variable exists and is truthy
freeF free(&self) -> i64Free the context
dropF drop(&self) -> i64Alias for free (RAII pattern)

Truthy values: Non-empty strings except "0" and "false"

Template

Compiled template ready for rendering.

S Template {
    source: str,
    handle: i64    # Opaque pointer to parsed template
}

Methods

MethodSignatureDescription
parseF parse(source: str) -> TemplateParse a template string
renderF render(&self, ctx: &TemplateCtx) -> strRender template with context
freeF free(&self) -> i64Free the template
dropF drop(&self) -> i64Alias for free (RAII pattern)

Functions

Core Functions

FunctionSignatureDescription
template_ctx_newF template_ctx_new() -> TemplateCtxCreate a new template context
template_parseF template_parse(source: str) -> TemplateParse a template string
template_renderF template_render(tmpl: &Template, ctx: &TemplateCtx) -> strRender a template with context

Convenience Functions

FunctionSignatureDescription
template_quick_renderF template_quick_render(source: str, ctx: &TemplateCtx) -> strParse and render in one step
template_render_varF template_render_var(source: str, key: str, value: str) -> strRender with single variable

HTML & Filters

FunctionSignatureDescription
html_escapeF html_escape(input: str) -> strEscape HTML entities (&, <, >, ", ')
apply_filterF apply_filter(value: str, filter_name: str) -> strApply named filter to value

Supported filters: "upper", "lower", "escape", "trim", "length"

Partials

FunctionSignatureDescription
template_register_partialF template_register_partial(name: str, source: str) -> i64Register a partial template by name

Template Syntax

Variable Interpolation

{{ variable }}           # Replace with variable value
{{ user.name }}          # Nested access (if supported)
{{ variable | upper }}   # Apply filter to variable

Conditionals

{% if condition %}
    Content when true
{% endif %}

{% if user %}
    Hello, {{ user }}!
{% endif %}

Loops

{% for item in list %}
    Item: {{ item }}
{% endfor %}

Partials

{% include "header" %}
{% include "footer" %}

Usage Examples

Basic Example

U std/template

F main() -> i64 {
    ctx := TemplateCtx::new()
    ctx.set_str("name", "World")

    tmpl := Template::parse("Hello, {{ name }}!")
    result := tmpl.render(&ctx)
    # result is "Hello, World!"

    tmpl.free()
    ctx.free()
    0
}

Chaining Context Variables

U std/template

F main() -> i64 {
    ctx := TemplateCtx::new()
        .set_str("title", "My Page")
        .set_str("user", "Alice")
        .set_int("count", 42)

    tmpl := Template::parse("{{ title }}: {{ user }} ({{ count }})")
    result := tmpl.render(&ctx)
    # result is "My Page: Alice (42)"

    tmpl.free()
    ctx.free()
    0
}

Quick Render (One-Shot)

U std/template

F main() -> i64 {
    ctx := TemplateCtx::new().set_str("name", "Bob")
    result := template_quick_render("Hi, {{ name }}!", &ctx)
    # result is "Hi, Bob!"
    ctx.free()
    0
}

Single Variable Render

U std/template

F main() -> i64 {
    result := template_render_var(
        "Welcome, {{ user }}!",
        "user",
        "Charlie"
    )
    # result is "Welcome, Charlie!"
    0
}

HTML Escaping

U std/template

F main() -> i64 {
    unsafe := "<script>alert('XSS')</script>"
    safe := html_escape(unsafe)
    # safe is "&lt;script&gt;alert(&#39;XSS&#39;)&lt;/script&gt;"
    0
}

Applying Filters

U std/template

F main() -> i64 {
    upper := apply_filter("hello", "upper")   # "HELLO"
    lower := apply_filter("WORLD", "lower")   # "world"
    trimmed := apply_filter("  hi  ", "trim") # "hi"
    len := apply_filter("test", "length")     # "4"
    0
}

Conditionals and Truthiness

U std/template

F main() -> i64 {
    ctx := TemplateCtx::new()
        .set_str("user", "Alice")
        .set_str("admin", "")

    # is_truthy returns 1 for non-empty, 0 for empty/"0"/"false"
    has_user := ctx.is_truthy("user")    # 1
    is_admin := ctx.is_truthy("admin")   # 0

    ctx.free()
    0
}

Performance Notes

  • Templates are compiled once and can be rendered multiple times
  • Rendering uses a 64KB preallocated buffer for performance
  • Context variable lookup is O(n) with max 64 variables
  • For repeated rendering, parse once and reuse the Template

Memory Management

  • Template contexts and parsed templates must be explicitly freed
  • Rendered strings are allocated and owned by caller
  • Use drop() methods for RAII-style cleanup
  • template_quick_render automatically frees the template
  • template_render_var automatically frees both template and context