Let's start with a very simple example. The following template prints 'Hello [Person's first name]', where person is passed as one of the template's parameters.
<btl:template xmlns:btl="http://btl.sourceforge.net/">
<btl:main>
<btl:param name="person"/>
<h1>Hi ${person.firstName}!</h1>
<p>Welcome to <img src="./btl.gif"/> & have fun!</p>
<p>Your homepage is <a href="${person.homepage}">here</a>.</p>
</btl:main>
</btl:template>Please notice here:
http://btl.sourceforge.net/" is the BTL's namespace.
All BTL's directives and instructions are in this namespacebtl:main" is a template's entry point,
similar to the Java's main method.${person.firstName}" is used to output "firstName" property
of the "person" bean. Notice that the same construct can be used in an
attribute value.${...}" is used, we don't care if the result contains
special characters (such as ampersand or angle brackets) or not,
they're automatically handled by the BTL.&".img" tag is closed, although HTML doesn't require this.
It has to be closed in BTL, b/c valid XML is required at all times.
However, HTML renderer will output this tag according to the HTML
standard.<btl:template xmlns:btl="http://btl.sourceforge.net/">
<btl:main>
<btl:param name="person"/>
<btl:if expr="person">
<h1>Hi ${person.firstName}!</h1>
</btl:if>
<p>Siblings:
<btl:for-each var="sibling" expr="person.siblings" status="s">
<btl:if expr="s.hasPrev">, </btl:if>
<btl:text>${sibling.fullName}</btl:text>
</btl:for-each>
</p>
</btl:main>
</btl:template>true if
it's not empty, object is evaluated to true if it's not
null, collection is evaluated to true if it's not empty,
etc.<btl:template xmlns:btl="http://btl.sourceforge.net/"
xmlns:bte="http://btl.sourceforge.net/exec"
xmlns:my="http://example.com/my">
<btl:macro name="hello">
<btl:param name="person"/>
<btl:text>Hi ${person.firstName}!</btl:text>
</btl:macro>
<btl:macro name="my:hello">
<btl:param name="person"/>
<btl:text>Hi again ${person.firstName}!</btl:text>
</btl:macro>
<btl:main>
<btl:param name="person"/>
<h1>
<btl:call name="hello">
<btl:param name="person" expr="person"/>
</btl:call>
</h1>
<h1>
<btl:call name="my:hello">
<btl:param name="person" expr="person"/>
</btl:call>
</h1>
<!-- OR -->
<h1><bte:hello person="person"/></h1>
<h1><my:hello person="person"/></h1>
</btl:main>
</btl:template>http://btl.sourceforge.net/exec" namespace should be
used for macros in the default namespace.btl:param".true for macro to be selected from all possible
macros.
Optional attribute "priority" can be used to resolve potential
matching conflicts.
<btl:template xmlns:btl="http://btl.sourceforge.net/"
xmlns:bte="http://btl.sourceforge.net/exec">
<btl:match-macro name="renderPerson" target="p">
<btl:text>${p.fullName}</btl:text>
</btl:match-macro>
<btl:match-macro name="renderPerson" target="p" match="p.age lt 18">
<btl:text>${p.firstName}</btl:text>
</btl:match-macro>
<btl:match-macro name="renderPerson" target="p" match="p.age gte 18 and p.gender == 'male'">
<btl:text>Mr. ${p.lastName}</btl:text>
</btl:match-macro>
<btl:match-macro name="renderPerson" target="p" match="p.age gte 18 and p.gender == 'female'">
<btl:text>Mrs. ${p.lastName}</btl:text>
</btl:match-macro>
<btl:main>
<btl:param name="person"/>
<h1>Hi
<btl:apply name="renderPerson" target="person"/>
</h1>
<!-- OR -->
<h1>Hi <bte:renderPerson btl:target="person"/></h1>
</btl:main>
</btl:template>
btl:macro, there're two forms
of invoking match-macro: explicit (using btl:apply)
and implicit (using macro's name with namespace or default
"http://btl.sourceforge.net/exec" namespace).btl:nested)