Template Syntax

Expressions

An identifier by itself refers to a scalar in the root hash of the data model:

${foo}

The delimiters mean "print the expression's value here". An expression that has no referent, or whose referent is null, produces no output. Expressions inside template tags don't have these delimiters:

<if foo>
    hello
</if>

This prints "hello" if the boolean value of foo is true. In templates, undefined, null, and empty values evaluate to false; all other values evaluate to true. Undefined, null, and empty values are considered to be equal.

If two identifiers are separated by a dot, the one on the left is a hash; the one on the right is the name of a key in that hash:

<p>First Name: ${book.author.firstName}

When an identifier followed by an expression in brackets, the expression is evaluated at run time as the name of a hash key. The following are all equivalent, if propName equals "bar" and propStart equals "ba":

foo.bar
foo["bar"]
foo[propName]
foo["ba" + "r"]
foo[propStart + "r"]

You can chain together dynamic hash keys. All of the following are equivalent:

foo.bar.baz.bing
foo["bar"]["baz"]["bing"]
foo["bar"].baz["bing"]

On a variable, which is a TemplateListModel, you can use an numerical index, like this:

myList[1]
myList[index]

Where index is a TemplateNumberModel with a numeric value (eg, 1).

In addition to the dot and bracket operators, many other operators are supported in expressions:

Boolean operators

Operator Usage Meaning
! !exp Logical not
== exp == exp Equality (string or number comparison)
eq exp eq exp
!= exp != exp Inequality (string or number comparison)
ne exp ne exp
&& exp && exp Logical and
and exp and exp
|| exp || exp Logical or
or exp or exp
lt exp lt exp Less than (numeric comparison)
le exp le exp Less than or equal (numeric comparison)
gt exp gt exp Greater than (numeric comparison)
ge exp ge exp Greater than or equal (numeric comparison)
? : exp ? exp : exp Conditional ternary

String operators

Operator Usage Meaning
+ exp + exp String concatenation

Numeric operators

Operator Usage Meaning
+ exp + exp Add
- exp - exp Subtract
* exp * exp Multiply
/ exp / exp Divide
% exp % exp Modulo

Method operators

Operator Usage Meaning
#lambda #lambda(args) exp Anonymous method

String literals are delimited by either single or double quotes. A backslash in a string literal can be used to escape a double quote. To include a backslash character, use \\. Operators have standard precedence, and you can use nested parentheses.

Number literals have no delimiters. They may be optionally preceded by a minus sign to indicate a negative number. Numbers are whole numbers only, and no decimal points can be used.

Boolean literals are preceded by the # sign. The boolean literals allowed are:

#true
#false
#empty

An identifier followed a pair of parentheses is a method call:

foo()
foo("hello")
deal(king, queen, spade)

A method, which is a TemplateMethodModel, can return any type of TemplateModel, or null. You can chain together method calls if each one returns a model containing the next method:

foo().bar()

Here, foo() returns a hash in which the key bar's value is a method object that executes bar().

A comment looks like this:

<comment>
    Comment text...
</comment>

Any text or markup inside the comment is ignored. Comments cannot be nested inside other comments.

Here are some more examples of syntactically valid expressions:

!(color == "blue" || color == "violet")

"customer" + customer.number

foo && (!(bar || baz) || bing)

eventManager.getEvent(eventID).importance

If you use a boolean expression for its string value (not something you'll often need to do), its string value is "true" if it evaluates to true, otherwise null.