Expressions

When you supply values for interpolations or directive parameters you can use variables or more complex expressions. For example, if x is the number 8 and y is 5, the value of (x + y)/2 resolves to the numerical value 6.5.

Before we go into details, let's see some concrete examples:

  • When you supply value for interpolations: The usage of interpolations is ${expression} where expression gives the value you want to insert into the output as text. So ${(5 + 8)/2} prints "6.5" to the output (or possibly "6,5" if the language of your output is not US English).

  • When you supply a value for the directive parameter: You have already seen the if directive in the Getting Started section. The syntax of this directive is: <#if expression>...</#if>. The expression here must evaluate to a boolean value. For example in <#if 2 < 3> the 2 < 3 (2 is less than 3) is an expression which evaluates to true.

Quick overview (cheat sheet)

This is a reminder for those of you who already know FreeMarker or are just experienced programmers:

See also: Operator precedence

Specify values directly

Often you want to specify a value directly and not as a result of some calculations.

Strings

To specify a string value directly you give the text in quotation marks, e.g.: "some text" or in apostrophe-quote, e.g. 'some text'. The two forms are equivalent. If the text itself contains the character used for the quoting (either " or ') or backslashes, you have to precede them with a backslash; this is called escaping. You can type any other character, including line breaks, in the text directly. Example:

Template
${"It's \"quoted\" and
this is a backslash: \\"}

${'It\'s "quoted" and
this is a backslash: \\'}

will print:

Output
It's "quoted" and
this is a backslash: \

It's "quoted" and
this is a backslash: \
Note:

Of course, you could simply type the above text into the template, without using ${...}. But we do it here just for the sake of example, to demonstrate expressions.

This is the list of all supported escape sequences. All other usage of backlash in string literals is an error and any attempt to use the template will fail.

Escape sequence Meaning
\" Quotation mark (u0022)
\' Apostrophe (a.k.a. apostrophe-quote) (u0027)
\{ Opening curly brace: {
\= Equals character: = (Supported since FreeMarker 2.3.28.)
\\ Back slash (u005C)
\n Line feed (u000A)
\r Carriage return (u000D)
\t Horizontal tabulation (a.k.a. tab) (u0009)
\b Backspace (u0008)
\f Form feed (u000C)
\l Less-than sign: <
\g Greater-than sign: >
\a Ampersand: &
\xCode Character given with its hexadecimal Unicode code (UCS code)

The Code after the \x is 1 to 4 hexadecimal digits. For example this all put a copyright sign into the string: "\xA9 1999-2001", "\x0A9 1999-2001", "\x00A9 1999-2001". When the character directly after the last hexadecimal digit can be interpreted as hexadecimal digit, you must use all 4 digits or else FreeMarker will misunderstand you.

Note that the character sequence ${ and #{ (and rarely [= instead, depending on the configured syntax) has special meaning. They are used to insert the value of expressions (typically: the value of variables, as in "Hello ${user}!"). This will be explained later. If you want to print ${ or #{ (or [=), you should either use raw string literals as explained below, or escape the { like in "foo $\{bar}" (or the = like in "foo [\=bar]").

A special kind of string literals is the raw string literals. In raw string literals, backslash and ${ have no special meaning, they are considered as plain characters. To indicate that a string literal is a raw string literal, you have to put an r directly before the opening quotation mark or apostrophe-quote. Example:

Template
${r"${foo}"}
${r"C:\foo\bar"}

will print:

Output
${foo}
C:\foo\bar

Numbers

To specify a numerical value directly you type the number without quotation marks. You have to use the dot as your decimal separator and must not use any grouping separator symbols. You can use - or + to indicate the sign (+ is redundant). Scientific notation is not yet supported (so 1E3 is wrong). Also, you cannot omit the 0 before the decimal separator (so .5 is wrong).

Examples of valid number literals: 0.08, -5.013, 8, 008, 11, +11

Note that numerical literals like 08, +8, 8.00 and 8 are totally equivalent as they all symbolize the number eight. Thus, ${08}, ${+8}, ${8.00} and ${8} will all print exactly same.

Since FreeMarker 2.3.35, hexadecimal literals are also supported, using the 0x (or 0X) prefix followed by hexadecimal digits (0-9, a-f, A-F). For example 0xFF is the number 255, and 0x100 is 256. Hexadecimal literals can only specify whole numbers. There's no limit on the number of digits: the value is created as an Integer if it fits into a 32-bit signed integer, as a Long if it fits into a 64-bit signed integer, and as a BigInteger otherwise (though this can be customized via a custom freemarker.core.ArithmeticEngine). Unless a - sign is prepended, as in -0x10, hexadecimal literals are always interpreted as positive numbers.

Booleans

To specify a boolean value you write true or false. Don't use quotation marks.

Sequences

To specify a literal sequence, you list the sub variables separated by commas, and put the whole list into square brackets. For example:

Template
<#list ["foo", "bar", "baz"] as x>
${x}
</#list>

will print:

Output
foo
bar
baz
 

The items in the list are expressions, so you can do this for example: [2 + 2, [1, 2, 3, 4], "foo"]. Here the first subvariable will be the number 4, the second will be another sequence, and the third subvariable will be the string "foo".

Ranges

Ranges are just sequences, but they are created by specifying what range of whole numbers they contain, instead of specifying their items one by one. For example, 0..<m, assuming the m variable stores 5, will give a sequence that contains [0, 1, 2, 3, 4]. Ranges are primarily used for iterating over a range of numbers with <#list ...> and for slicing sequences and slicing strings.

The generic forms of range expressions are (where start and end can be any expression that evaluates to a number):

  • start..end: Range with inclusive end. For example, 1..4 gives [1, 2, 3, 4], and 4..1 gives [4, 3, 2, 1]. Beware, ranges with inclusive end never give an empty sequence, so 0..length-1 is WRONG, because when length is 0 it gives [0, -1].