Template engine with variable interpolation, conditionals, loops, filters, and partials
U std/template
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
Constant Value Description
NODE_TEXT0 Raw text node
NODE_VAR1 Variable interpolation {{ var }}
NODE_IF2 Conditional block {% if cond %}
NODE_FOR3 Loop block {% for item in list %}
NODE_INCLUDE4 Include partial {% include "name" %}
NODE_FILTER5 Variable with filter {{ var | filter }}
Constant Value Description
FILTER_NONE0 No filter applied
FILTER_UPPER1 Convert to uppercase
FILTER_LOWER2 Convert to lowercase
FILTER_ESCAPE3 HTML escape
FILTER_TRIM4 Trim whitespace
FILTER_LENGTH5 Get string length
Constant Value Description
VAL_STR0 String value
VAL_INT1 Integer value
VAL_LIST2 Array of string pointers
Constant Value Description
TPL_MAX_NODES256 Maximum template nodes
TPL_MAX_VARS64 Maximum context variables
TPL_BUFFER_SIZE65536 Render buffer size (64KB)
TPL_KEY_SIZE128 Maximum key length
TPL_VAL_SIZE4096 Maximum value length
Template context stores key-value pairs for variable interpolation.
S TemplateCtx {
handle: i64 # Opaque pointer to C runtime context
}
Method Signature Description
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"
Compiled template ready for rendering.
S Template {
source: str,
handle: i64 # Opaque pointer to parsed template
}
Method Signature Description
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)
Function Signature Description
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
Function Signature Description
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
Function Signature Description
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"
Function Signature Description
template_register_partialF template_register_partial(name: str, source: str) -> i64Register a partial template by name
{{ variable }} # Replace with variable value
{{ user.name }} # Nested access (if supported)
{{ variable | upper }} # Apply filter to variable
{% if condition %}
Content when true
{% endif %}
{% if user %}
Hello, {{ user }}!
{% endif %}
{% for item in list %}
Item: {{ item }}
{% endfor %}
{% include "header" %}
{% include "footer" %}
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
}
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
}
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
}
U std/template
F main() -> i64 {
result := template_render_var(
"Welcome, {{ user }}!",
"user",
"Charlie"
)
# result is "Welcome, Charlie!"
0
}
U std/template
F main() -> i64 {
unsafe := "<script>alert('XSS')</script>"
safe := html_escape(unsafe)
# safe is "<script>alert('XSS')</script>"
0
}
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
}
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
}
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
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