util.xtemplate

util.xtemplate implements a string template language, similar to util.interpolation but different. Notably, it takes as input an XML stanza rather than a Lua table.

For example:

local st = require "util.stanza"
local xtemplate = require "util.xtemplate"

print(xtemplate.render("{greet}", st.stanza("root"):text_tag("greet", "Hello")));
--> Hello

Syntax

"{" path { "|" function { "(" argument ")" }? {"{" template "}"}? }* "}"

The variable interpolation is based on the stanza.find(path) method, so {path} would be replaced with root:find("path") or rather its text content.

Built-in functions

In examples, XML is the parse() function from util.xml.

local XML = require"util.xml".parse;

and, or

Conditional templates, allows fallback values or rendering parts if some value is present.

render("{foo/bar|or{Nope}}", XML [[
<root>
  <foo>
    <bar>Hello</bar>
  </foo>
</root>
]])
-- > Hello

render("{foo/bar|or{Nope}}", XML [[
<root>
  <foo>
</root>
]])
-- > Nope

These functions can take an optional path to base the condition on instead of the “current” path (foo/bar in previous examples).

render("{foo|and(yes){{print}}}", XML[[
<root>
  <foo>
    <yes/>
    <print>Hello</print>
  </foo>
</root>
]])
--> Hello

each

Allows iterating over XML element children.

{foo/bar|each(baz){this}}

given

<foo>
  <bar>
    <baz>Hello</baz>
    <baz>World</baz>
  </bar>
</foo>

would result in

thisthis

Custom filter functions

In addition to these built-in functions, further filters can be passed as table argument to render() like so:

render("{foo/bar|upper}", XML[[
<root>
  <foo>
    <bar>Hello</bar>
  </foo>
</root>
]], nil, { upper = string.upper });
--> HELLO