util.interpolation
util.interpolation
implements a string template language, primarily meant for interpolation of variables into HTML.
An example:
local st = require"util.stanza"
local render = require"util.interpolation".new("%b{}", st.xml_escape);
local template = [[
<title>{title}</title>
<h1>{title}</h1>
<p>Hello, {name}! Welcome to {here}.</p>
]]
print(render(template, { title = "Welome", name = "Alice", here = "wonderland" })
new
The module exposes a single new()
function, which takes 2 or 3 arguments and returns a renderer function.
The first argument is the pattern that signifies variables. The first capture must have exactly one character before and after the variable name. It is recommended to use the ''%bxy'' pattern construct. To allow a longer pre- or suffix, a capture can be used around the inner two characters, so a longer pattern may be "\\var(%b{})"
for \var(variable)
.
The second argument must be an escaping function for the target text format. For HTML or XML the xml_escape
function from util.stanza is suitable. To disable escaping, simply pass function(x) return x end
.
The third argument is an optional table of filter functions. See the Filters section below.
The returned function takes two arguments, a template string and a table of variables.
Modifiers
No escaping
To pass a variable through raw, without escaping, put an exclamation mark as last character: {foo!}
.
Optional variables
Normally, if a variable used in the template is left out, the original template text is passed through unchanged. This can be changed by including a question mark: {foo?}
, then the entire expression will be removed in the output.
This fallback text can contain nested template expressions, like {foo?empty, but {bar}}
.
Conditional subtemplate
Similar to fallback text, but the other way around: {foo&the variable foo is {foo}}
.
Iterating over arrays and maps
To render a list of things using the same template the expression {list#subtemplate with {idx} and {item}}
can be used. Each item will be available in the sub-template as an item
variable, and its index will be idx
.
local template = [[
<ul>{items#
<li id="item-{idx}">{item}</li>}
</ul>
]]
print(render(template, { items = { "lorem", "ipsum", "dolor", "sit", "amet" } }))
Iterating over arbitrary key-value tables is done like {table%{idx} = {item}}
.
Filters
The third argument to new
is a table of filter functions. To invoke these, the pipe symbol is used, like {foo|uppercase}
. Multiple filters may be chained. The filter functions get the input as one argument. Returning nil cancels further chained filters. May be combined with one final modifier.