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:
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 |
Operator | Usage | Meaning |
---|---|---|
+ |
exp + exp |
String concatenation |
Operator | Usage | Meaning |
---|---|---|
+ |
exp + exp |
Add |
- |
exp - exp |
Subtract |
* |
exp * exp |
Multiply |
/ |
exp / exp |
Divide |
% |
exp % exp |
Modulo |
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.
Previous: Introduction | Next: Lists |