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")));
--> HelloSyntax
template ::= "{" path { "|" function { "(" path ")" }? {"{" template "}"}? }* "}"
path ::= See the :find() method in util.stanza
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>
]])
-- > NopeThese 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>
]])
--> Helloeach
Allows iterating over XML element children. When the path passed
consists of more than one element (e.g. foo/bar, as opposed
to just foo) then the child tag to iterate must be given as
an argument in parenthesis.
{foo/bar|each(baz){this}}
given
<foo>
<bar>
<baz>Hello</baz>
<baz>World</baz>
</bar>
</foo>would result in
thisthis
Another example, this time without an argument:
{entry|each{
# {title}
by {author/name}
{content}
}}
<feed>
<entry>
<title>Hello World</title>
<author>
<name>Juliet</name>
</author>
<content>Lorem ipsum.</content>
</entry>
<entry>
<title>Another Post</title>
<author>
<name>Romeo</name>
</author>
<content>Dolor sit amet.</content>
</entry>
</feed>would result in
# Hello World
by Juliet
Lorem ipsum.
# Another Post
by Romeo
Dolor sit amet.
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