ERB/EJS-style string templating engine for Turmeric. Interpolate
variables, branch with if/else, iterate with for, and bind locals
with let -- all in plain text templates with no embedded logic
language.
tur-template is a Tier 1 spice (pure Turmeric, no C deps beyond the
inline-C renderer). It parses template strings containing <%= var %>
interpolation, <% if cond %>...<% else %>...<% end %> conditionals,
<% for [x list] %>...<% end %> loops, and <% let x val %>...<% end %>
bindings, then renders them against an environment of string bindings.
The engine is designed for server-side HTML generation: tourist uses
it for view rendering. Templates are plain text (typically .html.tur
files); the renderer returns a heap-allocated cstr that the caller
frees.
:spices {
"template" {:url "https://github.com/turmeric-lang/turmeric-spices"
:ref "template-v0.2.0"
:subdir "spices/template"}
}
(import template/env :refer [env-new env-set env-free])
(import template/render :refer [render])
(let [e (env-new)]
(env-set e "title" "Greetings")
(env-set e "name" "Roger")
(println (render "<h1><%= title %></h1><p>Welcome, <%= name %>.</p>" e))
(env-free e))
(import template/env :refer [env-new env-set env-free])
(import template/render :refer [render-file])
(let [e (env-new)]
(env-set e "title" "Greetings")
(env-set e "name" "Roger")
(let [r (render-file "template.html.tur" e)]
(if (ok? r)
(println (ok-val r))
(println (err-val r))))
(env-free e))
| Syntax | Meaning |
|---|---|
<%= var %> |
Interpolate the value of var, HTML-escaped |
<%== var %> |
Interpolate the value of var verbatim (trusted markup, non-HTML output) |
<% if cond %>...<% else %>...<% end %> |
Conditional branch (truthy = non-empty string) |
<% for [x list] %>...<% end %> |
Iterate over a list binding |
<% let x val %>...<% end %> |
Bind x to val for the body |
<%% ... %> |
Literal <% ... %> (escaped) |
Since 0.3.0, <%= var %> HTML-escapes the value: &, <, >, " and
' become &, <, >, " and '. That makes a value
safe in element content and inside a quoted attribute value, so a name taken
from a URL or a form cannot inject markup. It does not make a value safe in
every position: an unquoted attribute, a <script> or <style> body, an
on* handler, or a URL attribute given javascript:... still need care.
<%== var %> writes the value verbatim. Use it for markup you produced and
trust, and for templates whose output is not HTML (plain-text email, config
files), where entities would be wrong.
| Module | Exports |
|---|---|
template/render |
render, render-file, render-ast |
template/env |
env-new, env-set, env-set-list, env-get, env-has?, env-free |
template/token |
lex, token accessors, tokens-free |
template/parse |
parse, node accessors, nodes-free |
template/tree |
Tpl tree constructors and accessors |
An Env is a stack of key-to-string bindings. env-set adds or shadows
a scalar binding; env-set-list adds an iterable binding consumed by
for loops. The renderer pushes temporary bindings during for/let
blocks and pops them after the body completes.