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
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.
("{foo/bar|or{Nope}}", XML [[
render<root>
<foo>
<bar>Hello</bar>
</foo>
</root>
]])
-- > Hello
("{foo/bar|or{Nope}}", XML [[
render<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).
("{foo|and(yes){{print}}}", XML[[
render<root>
<foo>
<yes/>
<print>Hello</print>
</foo>
</root>
]])
--> Hello
each
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:
("{foo/bar|upper}", XML[[
render<root>
<foo>
<bar>Hello</bar>
</foo>
</root>
]], nil, { upper = string.upper });
--> HELLO