blob: a04c8b7c65866070ee757a13e3c167bd1d01d8fb [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<book conformance="docgen" version="5.0" xml:lang="en"
xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ns5="http://www.w3.org/1999/xhtml"
xmlns:ns4="http://www.w3.org/2000/svg"
xmlns:ns3="http://www.w3.org/1998/Math/MathML"
xmlns:ns="http://docbook.org/ns/docbook">
<title>FreeMarker Manual</title>
<subtitle>For FreeMarker 2.3.20</subtitle>
<preface xml:id="preface">
<title>Preface</title>
<section>
<title>What is FreeMarker?</title>
<para>FreeMarker is a <emphasis>template engine</emphasis>: a generic
tool to generate text output (anything from HTML to autogenerated source
code) based on templates. It's a Java package, a class library for Java
programmers. It's not an application for end-users in itself, but
something that programmers can embed into their products.</para>
<para>FreeMarker is designed to be practical for the generation of
<emphasis>HTML Web pages</emphasis>, particularly by servlet-based
applications following the <link linkend="gloss.MVC">MVC (Model View
Controller) pattern</link>. The idea behind using the MVC pattern for
dynamic Web pages is that you separate the designers (HTML authors) from
the programmers. Everybody works on what they are good at. Designers can
change the appearance of a page without programmers having to change or
recompile code, because the application logic (Java programs) and page
design (FreeMarker templates) are separated. Templates do not become
polluted with complex program fragments. This separation is useful even
for projects where the programmer and the HTML page author is the same
person, since it helps to keep the application clear and easily
maintainable.</para>
<para>Although FreeMarker has some programming capabilities, it is
<emphasis>not</emphasis> a full-blown programming language like PHP.
Instead, Java programs prepare the data to be displayed (like issue SQL
queries), and FreeMarker just generates textual pages that display the
prepared data using templates.</para>
<mediaobject>
<imageobject>
<imagedata fileref="figures/overview.png"/>
</imageobject>
</mediaobject>
<para>FreeMarker is <emphasis>not</emphasis> a Web application
framework. It is suitable as a component in a Web application framework,
but the FreeMarker engine itself knows nothing about HTTP or servlets.
It simply generates text. As such, it is perfectly usable in non-web
application environments as well. Note, however, that we provide
out-of-the-box solutions for using FreeMarker as the view component of
Model 2 frameworks such as Struts.</para>
<para>FreeMarker is <link
xlink:href="http://www.fsf.org/philosophy/free-sw.html">Free</link>,
released under a BSD-style license. It is <link
xlink:href="http://www.opensource.org/">OSI Certified Open Source
Software</link>. OSI Certified is a certification mark of the Open
Source Initiative.</para>
</section>
<section>
<title>What should I read?</title>
<para>If you are a ...</para>
<itemizedlist>
<listitem>
<para>designer, then you should read the <xref linkend="dgui"/> and
then you can look into the <xref linkend="ref"/> on an as-needed
basis for more specific details.</para>
</listitem>
<listitem>
<para>programmer, then you should read the <xref linkend="dgui"/>
guide first, then the <xref linkend="pgui"/> and then you can look
into the <xref linkend="ref"/> on an as-needed basis for more
specific details.</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Document conventions</title>
<para>Variable names, template fragments, Java class names, etc. are
written like this: <literal>foo</literal>.</para>
<para>If something should be replaced with a concrete value then it is
written in italics, as follows: <literal>Hello
<replaceable>yourName</replaceable>!</literal>.</para>
<para>Template examples are written like this:</para>
<programlisting role="template">something</programlisting>
<para>Data-model examples are written like this:</para>
<programlisting role="dataModel">something</programlisting>
<para>Output examples are written like this:</para>
<programlisting role="output">something</programlisting>
<para>Program examples are written like this:</para>
<programlisting role="unspecified">something</programlisting>
<remark>This paragraph is for the editors, and not visible for the
public</remark>
<para>In chapters <remark>this section is for the editors
too</remark>written for both designers and programmers fragments
addressed to programmers are written like this: <phrase
role="forProgrammers">This is for programmers only.</phrase></para>
<para>New terms are emphasized like this: <emphasis role="term">some new
term</emphasis></para>
</section>
<section>
<title>Contact</title>
<indexterm>
<primary>help</primary>
</indexterm>
<indexterm>
<primary>homepage</primary>
</indexterm>
<indexterm>
<primary>download</primary>
</indexterm>
<indexterm>
<primary>contact</primary>
</indexterm>
<para>For the latest version of FreeMarker and to subscribe to the
<emphasis>mailing lists</emphasis> visit the FreeMarker homepage: <olink
targetdoc="homepage"><phrase role="homepage"/></olink></para>
<para>If you <emphasis>need help</emphasis> or you have
<emphasis>suggestions</emphasis>, use the mailing lists (mail archives
can be searched without subscription) or the Web based forums. If you
want to <emphasis>report a bug</emphasis>, use the Web based bug
tracker, or the mailing lists. To find all of these visit <olink
targetdoc="homepage"><phrase role="homepage"/></olink>. Also, note that
we have a <link linkend="app_faq">FAQ</link> and <link
linkend="alphaidx">index</link>; use them.</para>
</section>
<section>
<title>About this document</title>
<para>If you find <emphasis>any mistakes</emphasis> (including
<emphasis>grammatical mistakes</emphasis>, <emphasis>typos</emphasis>,
typographical mistakes) or you find something <emphasis>misleading or
confusing</emphasis> in the documentation, or you have other
suggestions, please let me know! Email: ddekany at
users.sourceforge.net</para>
</section>
</preface>
<part xml:id="dgui">
<title>Template Author's Guide</title>
<chapter xml:id="dgui_quickstart">
<title>Getting Started</title>
<para>This chapter is a very rough introduction to FreeMarker. The
chapters after this will go over things in much greater detail.
Nonetheless, once you have read this chapter, you will be able to write
simple but useful FreeMarker templates.</para>
<section xml:id="dgui_quickstart_basics">
<title>Template + data-model = output</title>
<para>Assume you need a HTML page in an e-shop application, similar to
this:</para>
<programlisting role="output">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Welcome!&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Welcome <emphasis>Big Joe</emphasis>!&lt;/h1&gt;
&lt;p&gt;Our latest product:
&lt;a href="<emphasis>products/greenmouse.html</emphasis>"&gt;<emphasis>green mouse</emphasis>&lt;/a&gt;!
&lt;/body&gt;
&lt;/html&gt;</programlisting>
<para>Let's say that the user name ("Big Joe" above) should depend on
who the logged in Web page visitor is, and the latest product should
come from a database and thus it potentially changes at any moment. In
this situation you can't just enter the user name nor the URL and name
of the latest product into the HTML, you can't use static HTML.</para>
<para>FreeMarker's solution for this problem is using a <emphasis
role="term">template</emphasis> instead of the static HTML. The
template is the same as the static HTML, except that it contains some
instructions to FreeMarker that makes it dynamic:</para>
<programlisting role="template" xml:id="example.first">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Welcome!&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Welcome <emphasis>${user}</emphasis>!&lt;/h1&gt;
&lt;p&gt;Our latest product:
&lt;a href="<emphasis>${latestProduct.url}</emphasis>"&gt;<emphasis>${latestProduct.name}</emphasis>&lt;/a&gt;!
&lt;/body&gt;
&lt;/html&gt;</programlisting>
<para>The template is stored on the Web server, usually just like the
static HTML page would be. But whenever someone visits this page,
FreeMarker will step in and transform the template on-the-fly to plain
HTML by replacing the
<literal>${<replaceable>...</replaceable>}</literal>-s with up-to-date
content (e.g., replacing <literal>${user}</literal> with Big Joe or
whoever the visitor is) and send the result to the visitor's Web
browser. So the visitor's Web browser will receive something like the
first example HTML (i.e., plain HTML without FreeMarker instructions),
and it will not perceive that FreeMarker is used on the server. The
template file itself (which is, again, stored on the Web server) is
not changed during this, so the transformation will happen again and
again for each visiting. This ensures that the displayed information
is always up-to-date.</para>
<para>Now, you already may have noticed that the template contains no
instructions regarding how to find out who the current visitor is, or
how to query the database to find out what the latest product is. It
seems it just already know these values. And indeed that's the case.
An important idea behind FreeMarker (actually, behind Web MVC) is that
presentation logic and "business logic" should be separated. In the
template you only deal with presentation issues, that is, visual
design issues, formatting issues. The data that will be displayed
(such as the user name and so on) is prepared outside FreeMarker,
usually by routines written in Java language or other general purpose
language. So the template author doesn't have to know how these values
are calculated. In fact, the way these values are calculated can be
completely changed while the templates can remain the same, and also,
the look of the page can be completely changed without touching
anything but the template. This separation can be especially useful
when the template authors (designers) and the programmers are
different individuals.</para>
<para><indexterm>
<primary>data-model</primary>
</indexterm>While for FreeMarker (and for the template author) it's
not interesting <emphasis>how</emphasis> the data was calculated,
FreeMarker still have to know <emphasis>what</emphasis> the actual
data is. All the data that the template can use is packed into the so
called <emphasis role="term">data-model</emphasis>. It's created by
the already mentioned routines that calculate the data. As far as the
template author is concerned, the data-model is a tree-like structure
(like folders and files on your hard disk), that in this case could be
visualized as:</para>
<programlisting role="dataModel">(root)
|
+- <emphasis>user</emphasis> = "Big Joe"
|
+- <emphasis>latestProduct</emphasis>
|
+- <emphasis>url</emphasis> = "products/greenmouse.html"
|
+- <emphasis>name</emphasis> = "green mouse"</programlisting>
<para>(To prevent misunderstandings: The data-model is not a text
file, the above is just a visualization of a data-model for you. It's
from Java objects, but let that be the problem of the Java
programmers.)</para>
<para>Compare this with what you saw in the template earlier:
<literal>${user}</literal> and
<literal>${latestProduct.name}</literal>. As an analogy, the data
model is something like the file system of computers: the root and
<literal>latestProduct</literal> correspond to directories (folders)
and the <literal>user</literal>, <literal>url</literal> and
<literal>name</literal> correspond to files. <literal>url</literal>
and <literal>name</literal> are in the
<literal>latestProduct</literal> directory. So
<literal>latestProduct.name</literal> is like saying
<literal>name</literal> in the <literal>latestProduct</literal>
directory. But as I said, it was just a simile; there are no files or
directories here.</para>
<para>To recapitulate, a template and a data-model is needed for
FreeMarker to generate the output (like the HTML shown first):</para>
<para><phrase role="markedTemplate">Template</phrase> + <phrase
role="markedDataModel">data-model</phrase> = <phrase
role="markedOutput">output</phrase></para>
</section>
<section xml:id="dgui_quickstart_datamodel">
<title>The data-model at a glance</title>
<para>As you have seen, the data-model is basically a tree. This tree
can be arbitrarily complicated and deep, for example:</para>
<programlisting role="dataModel"
xml:id="example.qStart.dataModelWithHashes">(root)
|
+- animals
| |
| +- mouse
| | |
| | +- size = "small"
| | |
| | +- price = 50
| |
| +- elephant
| | |
| | +- size = "large"
| | |
| | +- price = 5000
| |
| +- python
| |
| +- size = "medium"
| |
| +- price = 4999
|
+- test = "It is a test"
|
+- whatnot
|
+- because = "don't know"</programlisting>
<para>The variables that act as directories (the root,
<literal>animals</literal>, <literal>mouse</literal>,
<literal>elephant</literal>, <literal>python</literal>,
<literal>whatnot</literal>) are called <emphasis
role="term">hashes</emphasis>. Hashes store other variables (the so
called <anchor
xml:id="topic.dataModel.subVar"/><emphasis>subvariables</emphasis>) by
a lookup name (e.g., "animals", "mouse" or "price").</para>
<para>The variables that store a single value
(<literal>size</literal>, <literal>price</literal>,
<literal>test</literal> and <literal>because</literal>) are called
<emphasis role="term">scalars</emphasis>.</para>
<para><anchor xml:id="topic.qStart.accessVariables"/>When you want to
use a subvariable in a template, you specify its path from the root,
and separate the steps with dots. To access the
<literal>price</literal> of a <literal>mouse</literal>, you start from
the root and go into <literal>animals</literal>, and then go into
<literal>mouse</literal> then go into <literal>price</literal>. So you
write <literal>animals.mouse.price</literal>. When you put the special
<literal>${<replaceable>...</replaceable>}</literal> codes around an
expression like this, you are telling FreeMarker to output the
corresponding text at that point.</para>
<para>There is one more important kind of variable: <emphasis
role="term">sequences</emphasis>. They are similar to hashes, but they
don't store names for the variables they contain. Instead, they store
the subvariables sequentially, and you can access them with a
numerical index. For example, in this data-model,
<literal>animals</literal> and <literal>whatnot.fruits</literal> are
sequences:</para>
<programlisting role="dataModel"
xml:id="example.qStart.dataModelWithSequences">(root)
|
+- animals
| |
| +- (1st)
| | |
| | +- name = "mouse"
| | |
| | +- size = "small"
| | |
| | +- price = 50
| |
| +- (2nd)
| | |
| | +- name = "elephant"
| | |
| | +- size = "large"
| | |
| | +- price = 5000
| |
| +- (3rd)
| |
| +- name = "python"
| |
| +- size = "medium"
| |
| +- price = 4999
|
+- whatnot
|
+- fruits
|
+- (1st) = "orange"
|
+- (2nd) = "banana"</programlisting>
<para>To access a subvariable of a sequence you use a numerical index
in square brackets. Indexes start from 0 (it's a programmer tradition
to start with 0), thus the index of the first item is 0, the index of
the second item is 1, and so on. So to get the name of the first
animal you write <literal>animals[0].name</literal>. To get the second
item in <literal>whatnot.fruits</literal> (which is the string
<literal>"banana"</literal>) you write
<literal>whatnot.fruits[1]</literal>.</para>
<para>Scalars can be further divided into these categories:</para>
<itemizedlist>
<listitem>
<para>String: Text, that is, an arbitrary sequence of characters
such as ''m'', ''o'', ''u'', ''s'', ''e'' above. For example the
<literal>name</literal>-s and <literal>size</literal>-s are
strings above.</para>
</listitem>
<listitem>
<para>Number: It's a numerical value, like the
<literal>price</literal>-s above. The string
<literal>"50"</literal> and the number <literal>50</literal> are
two totally different things in FreeMarker. The former is just a
sequence of two characters (which happens to be readable as a
number for humans), while the latter is a numerical value that you
can use, say, in arithmetical calculations.</para>
</listitem>
<listitem>
<para>Date/time: A date or time. Like the date an animal were
captured, or the time the shop opens.</para>
</listitem>
<listitem>
<para>Boolean: A true/false (yes/no, on/off, etc.) thing. Like
animals could have a <literal>protected</literal> subvariable,
which store if the animal is protected or not.</para>
</listitem>
</itemizedlist>
<para>Summary:</para>
<itemizedlist>
<listitem>
<para>The data-model can be visualized as a tree.</para>
</listitem>
<listitem>
<para>Scalars store a single value. The value can be a string or a
number or a date/time or a boolean.</para>
</listitem>
<listitem>
<para>Hashes are containers that store other variables and
associate them with a unique lookup name.</para>
</listitem>
<listitem>
<para>Sequences are containers that store other variables in an
ordered sequence. The stored variables can be retrieved via their
numerical index, starting from 0.</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="dgui_quickstart_template">
<title>The template at a glance</title>
<para>The simplest template is a plain HTML file (or whatever text
file -- FreeMarker is not confined to HTML). When the client visits
that page, FreeMarker will send that HTML to the client as is. However
if you want that page to be more dynamic then you begin to put special
parts into the HTML which will be understood by FreeMarker:</para>
<itemizedlist>
<listitem>
<para><literal>${<replaceable>...</replaceable>}</literal>:
FreeMarker will replace it in the output with the actual value of
the thing inside the curly brackets. They are called <emphasis
role="term">interpolation</emphasis>s. As an example see <link
linkend="example.first">the very first example</link>.</para>
</listitem>
<listitem>
<para><emphasis role="term">FTL tags</emphasis> (for FreeMarker
Template Language tags): FTL tags are a bit similar to HTML tags,
but they are instructions to FreeMarker and will not be printed to
the output. The name of these tags start with
<literal>#</literal>. (User-defined FTL tags use
<literal>@</literal> instead of <literal>#</literal>, but they are
an advanced topic.)</para>
</listitem>
<listitem>
<para><emphasis role="term">Comments:</emphasis> Comments are
similar to HTML comments, but they are delimited by
<literal>&lt;#--</literal> and <literal>--&gt;</literal>. Anything
between these delimiters and the delimiter itself will be ignored
by FreeMarker, and will not be written to the output.</para>
</listitem>
</itemizedlist>
<para>Anything not an FTL tag or an interpolation or comment is
considered as static text, and will not be interpreted by FreeMarker;
it is just printed to the output as is.</para>
<para>With FTL tags you refer to so-called <emphasis
role="term">directives</emphasis>. This is the same kind of
relationship as between HTML tags (e.g.:
<literal>&lt;table&gt;</literal> and
<literal>&lt;/table&gt;</literal>) and HTML elements (e.g., the
<literal>table</literal> element) to which you refer to with the HTML
tags. (If you don't feel this difference then just take "FTL tag" and
"directive" as synonyms.)</para>
<section>
<title>Examples of directives</title>
<para>Though FreeMarker has far more directives, in this quick
overview we will only look at three of the most commonly used
ones.</para>
<section>
<title>The if directive</title>
<para>With the <literal>if</literal> directive you can
conditionally skip a section of the template. For example, assume
that in the <link linkend="example.first">very first
example</link> you want to greet your boss, Big Joe, differently
from other users:</para>
<programlisting role="template">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Welcome!&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;
Welcome ${user}<emphasis>&lt;#if user == "Big Joe"&gt;</emphasis>, our beloved leader<emphasis>&lt;/#if&gt;</emphasis>!
&lt;/h1&gt;
&lt;p&gt;Our latest product:
&lt;a href="${latestProduct.url}"&gt;${latestProduct.name}&lt;/a&gt;!
&lt;/body&gt;
&lt;/html&gt;</programlisting>
<para>Here you have told FreeMarker that the '', our beloved
leader'' should be there only if the value of the variable
<literal>user</literal> is equal to the string <literal>"Big
Joe"</literal>. In general, things between <literal>&lt;#if
<replaceable>condition</replaceable>&gt;</literal> and
<literal>&lt;/#if&gt;</literal> tags are skipped if
<literal><replaceable>condition</replaceable></literal> is false
(the boolean value).</para>
<para>Let's detail the
<literal><replaceable>condition</replaceable></literal> used here:
The <literal>==</literal> is an operator that tests if the values
at its left and right side are equivalent, and the results is a
boolean value, true or false accordingly. On the left side of
<literal>==</literal> I have <link
linkend="topic.qStart.accessVariables">referenced a
variable</link> with the syntax that should be already familiar;
this will be replaced with the value of the variable. In general,
unquoted words inside directives or interpolations are treated as
references to variables. On the right side I have specified a
literal string. Literal strings in templates must
<emphasis>always</emphasis> be put inside quotation marks.</para>
<para>This will print "Pythons are free today!" if their price is
0:</para>
<programlisting role="template">&lt;#if animals.python.price == <emphasis>0</emphasis>&gt;
Pythons are free today!
&lt;/#if&gt;</programlisting>
<para>Similarly as earlier when a string was specified directly,
here a number is specified directly (<literal>0</literal>). Note
that the number is <emphasis>not</emphasis> quoted. If you quoted
it (<literal>"0"</literal>), FreeMarker were misinterpret it as a
string literal.</para>
<para>This will print "Pythons are not free today!" if their price
is not 0:</para>
<programlisting role="template">&lt;#if animals.python.price <emphasis>!=</emphasis> 0&gt;
Pythons are not free today!
&lt;/#if&gt;</programlisting>
<para>As you may have guessed, <literal>!=</literal> means not
equivalent.</para>
<para>You can write things like this too (using <link
linkend="example.qStart.dataModelWithHashes">the data-model used
to demonstrate hashes</link>):</para>
<programlisting role="template">&lt;#if <emphasis>animals.python.price &lt; animals.elephant.price</emphasis>&gt;
Pythons are cheaper than elephants today.
&lt;/#if&gt;</programlisting>
<para>With the <literal>&lt;#else&gt;</literal> tag you can
specify what to do if the condition is false. For example:</para>
<programlisting role="template">&lt;#if animals.python.price &lt; animals.elephant.price&gt;
Pythons are cheaper than elephants today.
<emphasis>&lt;#else&gt;</emphasis>
Pythons are not cheaper than elephants today.
&lt;/#if&gt;</programlisting>
<para>This prints ''Pythons are cheaper than elephants today.'' if
the price of python is less than the price of elephant, or else it
prints ''Pythons are not cheaper than elephants today.''</para>
<para>If you have a variable with boolean value (a true/false
thing) then you can use it directly as the
<literal><replaceable>condition</replaceable></literal> of
<literal>if</literal>:</para>
<programlisting role="template">&lt;#if animals.python.protected&gt;
Warning! Pythons are protected animals!
&lt;/#if&gt;</programlisting>
</section>
<section>
<title>The list directive</title>
<para>This is useful when you want to list something. For example
if you merge this template with the <link
linkend="example.qStart.dataModelWithSequences">data-model I used
earlier to demonstrate sequences</link>:</para>
<programlisting role="template">&lt;p&gt;We have these animals:
&lt;table border=1&gt;
&lt;tr&gt;&lt;th&gt;Name&lt;th&gt;Price
<emphasis>&lt;#list animals as being&gt;</emphasis>
&lt;tr&gt;&lt;td&gt;${<emphasis>being</emphasis>.name}&lt;td&gt;${<emphasis>being</emphasis>.price} Euros
<emphasis>&lt;/#list&gt;</emphasis>
&lt;/table&gt;</programlisting>
<para>then the output will be:</para>
<programlisting role="output">&lt;p&gt;We have these animals:
&lt;table border=1&gt;
&lt;tr&gt;&lt;th&gt;Name&lt;th&gt;Price
<emphasis>&lt;tr&gt;&lt;td&gt;mouse&lt;td&gt;50 Euros
&lt;tr&gt;&lt;td&gt;elephant&lt;td&gt;5000 Euros
&lt;tr&gt;&lt;td&gt;python&lt;td&gt;4999 Euros</emphasis>
&lt;/table&gt;</programlisting>
<para>The generic format of the <literal>list</literal> directive
is:</para>
<para><literal>&lt;#list <replaceable>sequence</replaceable> as
<replaceable>loopVariable</replaceable>&gt;<replaceable>repeatThis</replaceable>&lt;/#list&gt;</literal></para>
<para>The <literal><replaceable>repeatThis</replaceable></literal>
part will be repeated for each item in the sequence that you have
given with <literal><replaceable>sequence</replaceable></literal>,
one after the other, starting from the first item. In all
repetitions
<literal><replaceable>loopVariable</replaceable></literal> will
hold the value of the current item. This variable exists only
between the <literal>&lt;#list ...&gt;</literal> and
<literal>&lt;/#list&gt;</literal> tags.</para>
<para>As another example, we list the fruits of that example data
model:</para>
<programlisting role="template">&lt;p&gt;And BTW we have these fruits:
&lt;ul&gt;
<emphasis>&lt;#list whatnot.fruits as fruit&gt;</emphasis>
&lt;li&gt;${fruit}
<emphasis>&lt;/#list&gt;</emphasis>
&lt;ul&gt;</programlisting>
<para>The <literal>whatnot.fruits</literal> expression should be
familiar to you; it <link
linkend="topic.qStart.accessVariables">references a variable in
the data-model</link>.</para>
</section>
<section>
<title>The include directive</title>
<para>With the <literal>include</literal> directive you can insert
the content of another file into the template.</para>
<para>Suppose you have to show the same copyright notice on
several pages. You can create a file that contains the copyright
notice only, and insert that file everywhere where you need that
copyright notice. Say, you store this copyright notice in
<literal>copyright_footer.html</literal>:</para>
<programlisting role="template">&lt;hr&gt;
&lt;i&gt;
Copyright (c) 2000 &lt;a href="http://www.acmee.com"&gt;Acmee Inc&lt;/a&gt;,
&lt;br&gt;
All Rights Reserved.
&lt;/i&gt;</programlisting>
<para>Whenever you need that file you simply insert it with the
<literal>include</literal> directive:</para>
<programlisting role="template">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Test page&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Test page&lt;/h1&gt;
&lt;p&gt;Blah blah...
<emphasis>&lt;#include "/copyright_footer.html"&gt;</emphasis>
&lt;/body&gt;
&lt;/html&gt;</programlisting>
<para>and the output will be:</para>
<programlisting role="output">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Test page&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Test page&lt;/h1&gt;
&lt;p&gt;Blah blah...
<emphasis>&lt;hr&gt;
&lt;i&gt;
Copyright (c) 2000 &lt;a href="http://www.acmee.com"&gt;Acmee Inc&lt;/a&gt;,
&lt;br&gt;
All Rights Reserved.
&lt;/i&gt;</emphasis>
&lt;/body&gt;
&lt;/html&gt;</programlisting>
<para>If you change the <literal>copyright_footer.html</literal>,
then the visitor will see the new copyright notice on all
pages.</para>
</section>
</section>
<section>
<title>Using directives together</title>
<para>You can use directives as many times on a page as you want,
and you can nest directives into each other similarly as you can
nest HTML elements into each other. For example this will list the
animals and print the name of large animals with bigger font:</para>
<programlisting role="template">&lt;p&gt;We have these animals:
&lt;table border=1&gt;
&lt;tr&gt;&lt;th&gt;Name&lt;th&gt;Price
<emphasis>&lt;#list animals as being&gt;</emphasis>
&lt;tr&gt;
&lt;td&gt;
<emphasis>&lt;#if being.size == "large"&gt;</emphasis>&lt;font size="+1"&gt;<emphasis>&lt;/#if&gt;</emphasis>
${being.name}
<emphasis>&lt;#if being.size == "large"&gt;</emphasis>&lt;/font&gt;<emphasis>&lt;/#if&gt;</emphasis>
&lt;td&gt;${being.price} Euros
<emphasis>&lt;/#list&gt;</emphasis>
&lt;/table&gt;</programlisting>
<para>Note that since FreeMarker does not interpret text outside FTL
tags, interpolations and comments, it doesn't see the above
<literal>font</literal> tags as badly nested ones.</para>
</section>
<section>
<title>Dealing with missing variables</title>
<para>In practice the data-model often has variables that are
optional (i.e., sometimes missing). To spot some typical human
mistakes, FreeMarker doesn't tolerate the referring to missing
variables unless you tell them explicitly what to do if the variable
is missing. Here we will show the two most typical ways of doing
that.</para>
<para><phrase role="forProgrammers">Note for programmers: A
non-existent variable and a variable with <literal>null</literal>
value is the same for FreeMarker, so the "missing" term used here
covers both cases.</phrase></para>
<para>Wherever you refer to a variable, you can specify a default
value for the case the variable is missing, by following the
variable name with a <literal>!</literal> and the default value.
Like in the following example, when <literal>user</literal> is
missing from data model, the template will behave like if
<literal>user</literal>'s value were the string
<literal>"Anonymous"</literal>. (When <literal>user</literal> isn't
missing, this template behaves exactly like if
<literal>!"Anonymous"</literal> were not there):</para>
<programlisting role="template">&lt;h1&gt;Welcome ${user<emphasis>!"Anonymous"</emphasis>}!&lt;/h1&gt;</programlisting>
<para>You can ask whether a variable isn't missing by putting
<literal>??</literal> after its name. Combining this with the
already introduced <literal>if</literal> directive you can skip the
whole greeting if the <literal>user</literal> variable is
missing:</para>
<programlisting role="template">&lt;#if <emphasis>user??</emphasis>&gt;&lt;h1&gt;Welcome ${user}!&lt;/h1&gt;&lt;/#if&gt;</programlisting>
<para>Regarding variable accessing with multiple steps, like
<literal>animals.python.price</literal>, writing
<literal>animals.python.price!0</literal> is correct only if
<literal>animals.python</literal> is never missing and only the last
subvariable, <literal>price</literal>, is possibly missing (in which
case here we assume it's <literal>0</literal>). If
<literal>animals</literal> or <literal>python</literal> is missing,
the template processing will stop with an "undefined variable"
error. To prevent that, you have to write
<literal>(animals.python.price)!0</literal>. In that case the
expression will be <literal>0</literal> even if
<literal>animals</literal> or <literal>python</literal> is missing.
Same logic goes for <literal>??</literal>;
<literal>animals.python.price??</literal> versus
<literal>(animals.python.price)??</literal>.</para>
</section>
</section>
</chapter>
<chapter xml:id="dgui_datamodel">
<title>Values, Types</title>
<section xml:id="dgui_datamodel_basics">
<title>Basics</title>
<note>
<para>It is assumed that you have already read the <xref
linkend="dgui_quickstart"/> chapter.</para>
</note>
<para>Understanding the concept of values and types is crucial for the
understanding of data-models. However, the concept of values and types
is not confined to data-models, as you will see.</para>
<section xml:id="topic.value">
<title>What is a value?</title>
<indexterm>
<primary>value</primary>
</indexterm>
<para><phrase role="forProgrammers">Real programmers can safely skip
this section.</phrase></para>
<para>Examples of <emphasis>values</emphasis> as you know the term
from the everyday math are 16, 0.5, and so on, i.e. numbers. In the
case of computer languages the value term has a wider meaning, as a
value needn't be a number. For example, take this data-model:</para>
<programlisting role="dataModel" xml:id="example.stdDataModel">(root)
|
+- user = "Big Joe"
|
+- today = Jul 6, 2007
|
+- todayHoliday = false
|
+- lotteryNumbers
| |
| +- (1st) = 20
| |
| +- (2st) = 14
| |
| +- (3rd) = 42
| |
| +- (4th) = 8
| |
| +- (5th) = 15
|
+- cargo
|
+- name = "coal"
|
+- weight = 40
</programlisting>
<para>We say that the <emphasis>value</emphasis> of the the
<literal>user</literal> variable is "Big Joe" (a string), the
<emphasis>value</emphasis> of <literal>today</literal> is Jul 6,
2007 (a date), the <emphasis>value</emphasis> of
<literal>todayHoliday</literal> is false (a boolean, ie. a yes/no
thing). The <emphasis>value</emphasis> of
<literal>lotteryNumbers</literal> is the sequence that contains 20,
14, 42, 8, 15. Surely <literal>lotteryNumbers</literal> is multiple
values in the sense that it <emphasis>contains</emphasis> multiple
values (for example, the 2nd item in it is a the
<emphasis>value</emphasis> 14), but still,
<literal>lotteryNumbers</literal> itself is a single value. It's
like a box that contains many other items; the whole box can be seen
as a single item. Last not least we also have the
<emphasis>value</emphasis> of <literal>cargo</literal>, which is a
hash (a box-like thing again).So, a value is something that can be
stored in a variable (e.g., in <literal>user</literal> or
<literal>cargo</literal> or <literal>cargo.name</literal>). But a
value need not be stored in a variable to be called a value, for
example we have the value 100 here:</para>
<programlisting role="template">&lt;#if cargo.weight &lt; <emphasis>100</emphasis>&gt;Light cargo&lt;/#if&gt;</programlisting>
<para>The temporaly result of a calculations are also called values,
like 20 and 120 when this template is executed (it will print
120):</para>
<programlisting role="template">${cargo.weight / 2 + 100}</programlisting>
<para>Explanation for this last: As the result of dividing the two
values, 40 (the weight of the cargo) and 2, a new value 20 is
created. Then 100 is added to it, so the value 120 is created. Then
120 is printed
(<literal>${<replaceable>...</replaceable>}</literal>), and the
template execution goes on and all these values gone.</para>
<para>Certainly now you feel what the value term means.</para>
</section>
<section>
<title>What is type?</title>
<para>Values have an important aspect, their type. For example the
type of the value of the <literal>user</literal> variable is string,
and the type of the value of the <literal>lotteryNumbers</literal>
variable is sequence. The type of a value is important because it
determines to a large extent how and where you can use the value.
Like <literal>${user / 2}</literal> is an error, but
<literal>${cargo.weight / 2}</literal> works and prints 20, since
division only does make sense for a number, but not for a string.
Or, using dot like in <literal>cargo.name</literal> does make sense
only if <literal>cargo</literal> is a hash. Or, you can list with
<literal>&lt;#list <replaceable>...</replaceable>&gt;</literal>
sequences only. Or, the condition of <literal>&lt;#if
...&gt;</literal> must be a boolean. And so on.</para>
<note>
<para>A little terminology... Saying "a boolean" or "a boolean
value" or "a value of type boolean" are all the same.</para>
</note>
<para xml:id="topic.multitype"><indexterm>
<primary>Multi-typed value</primary>
</indexterm>A value can have multiple types at the same time,
although it's rarely utilized. For example in the data-model below
<literal>mouse</literal> is both a string and a hash:</para>
<programlisting role="dataModel">(root)
|
+- mouse = "Yerri"
|
+- age = 12
|
+- color = "brown"</programlisting>
<para>If you merge this template with the above data-model:</para>
<programlisting role="template">${mouse} &lt;#-- uses mouse as a string --&gt;
${mouse.age} &lt;#-- uses mouse as a hash --&gt;
${mouse.color} &lt;#-- uses mouse as a hash --&gt;</programlisting>
<para>the output will be:</para>
<programlisting role="output">Yerri
12
brown</programlisting>
</section>
<section>
<title>The data-model is a hash</title>
<para>Looking at the various data-model examples you may already
realized: the thing marked as "(root)" is just a value of type hash.
When you write something like <literal>user</literal>, that means
that you want the "user" variable stored in the root hash. Like if
you were writing <literal>root.user</literal>, except that there is
no variable called "root" so that wouldn't work.</para>
<para>Some may get confused by the fact that our example data-model,
that is, the root hash, contains further hashes and sequences
(<literal>lotteryNumbers</literal> and <literal>cargo</literal>).
There is nothing special in that. A hash contains other variables,
and those variables have a value, which can be a string, a number,
etc., and of course it can be a hash or sequence as well. Because,
as it was explained earlier, a sequence or a hash is just a value,
like a string or a number is.</para>
</section>
</section>
<section xml:id="dgui_datamodel_types">
<title>The types</title>
<para>The suppored types are:</para>
<itemizedlist spacing="compact">
<listitem>
<para><link linkend="dgui_datamodel_scalar"
os="">Scalars:</link></para>
<itemizedlist spacing="compact">
<listitem>
<para>String</para>
</listitem>
<listitem>
<para>Number</para>
</listitem>
<listitem>
<para>Boolean</para>
</listitem>
<listitem>
<para>Date</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><link
linkend="dgui_datamodel_container">Containers:</link></para>
<itemizedlist spacing="compact">
<listitem>
<para>Hash</para>
</listitem>
<listitem>
<para>Sequence</para>
</listitem>
<listitem>
<para>Collection</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>Subroutines:</para>
<itemizedlist spacing="compact">
<listitem>
<para><link linkend="dgui_datamodel_method">Methods and
functions</link></para>
</listitem>
<listitem>
<para><link linkend="dgui_datamodel_userdefdir">User-defined
directives</link></para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>Miscellaneous/seldom used:</para>
<itemizedlist spacing="compact">
<listitem>
<para><link linkend="dgui_datamodel_node">Node</link></para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<section xml:id="dgui_datamodel_scalar">
<title>Scalars</title>
<anchor xml:id="topic.designer.scalarVariable"/>
<para>These are the basic, simple kind of values. They can
be:</para>
<itemizedlist>
<listitem>
<para><indexterm>
<primary>string</primary>
<secondary>the FTL value type</secondary>
</indexterm>String: It is simple text, e.g., the name of a
product.</para>
<para>If you want to give a string value directly in the
template, rather than use a variable that comes from the data
model, you write the text between quotation marks, e.g.,
<literal>"green mouse"</literal> or <literal>'green
mouse'</literal>. (More details regarding the syntax can be
found <link linkend="dgui_template_exp_direct_string"
xml:lang="">later</link>.)</para>
</listitem>
<listitem>
<para><indexterm>
<primary>number</primary>
<secondary>the FTL value type</secondary>
</indexterm>Number: For example the price of a product.
<phrase role="forProgrammers">Whole numbers and non-whole
numbers are not distinguished; there is only a single number
type. So for example 3/2 will be always 1.5, and never 1. Just
like if you are using a calculator.</phrase></para>
<para>If you want to give a numerical value directly in the
template, then you write for example: <literal>150</literal> or
<literal>-90.05</literal> or <literal>0.001</literal>. (More
details regarding the syntax can be found <link
linkend="dgui_template_exp_direct_number"
xml:lang="">later</link>.)</para>
</listitem>
<listitem>
<para><indexterm>
<primary>boolean</primary>
<secondary>the FTL value type</secondary>
</indexterm>Boolean: A boolean value represents a logical true
or false (yes or no). For example, if a the visitor has been
logged in or not. Typically you use booleans as the condition of
the <literal>if</literal> directive, like <literal>&lt;#if
loggedIn
&gt;<replaceable>...</replaceable>&lt;/#if&gt;</literal> or
<literal>&lt;#if price ==
0&gt;<replaceable>...</replaceable>&lt;/#if&gt;</literal>; in
the last case the result of the <literal>price == 0</literal>
part is a boolean value.</para>
<para>In the templates you can directly specify a boolean with
the reserved words <literal>true</literal> and
<literal>false</literal>.</para>
</listitem>
<listitem>
<para><indexterm>
<primary>date</primary>
<secondary>the FTL value type</secondary>
</indexterm><indexterm>
<primary>time</primary>
<secondary>the FTL value type</secondary>
</indexterm><indexterm>
<primary>date-time</primary>
<secondary>the FTL value type</secondary>
</indexterm>Date: A date variable stores date/time related
data. It has three variations:</para>
<itemizedlist>
<listitem>
<para>A date with day precision (often referred simply as
"date") as April 4, 2003</para>
</listitem>
<listitem>
<para>Time of day (without the date part), as 10:19:18 PM.
Time is stored with millisecond precision.</para>
</listitem>
<listitem>
<para>Date-time (sometimes called "time stamp") as April 4,
2003 10:19:18 PM. The time part is stored with millisecond
precision.</para>
</listitem>
</itemizedlist>
<para>Unfortunately, because of the limitations of the Java
platform, FreeMarker sometimes can't decide which parts of the
date are in use (i.e., if it is date-time, or a time of day,
etc.). The solution for this problem is an advanced topic that
will be discussed <link
linkend="ref_builtin_date_datetype">later</link>.</para>
<para>It is possible to define date values directly in
templates, but this is an advanced topic that will be explained
<link linkend="ref_builtin_string_date">later</link>.</para>
</listitem>
</itemizedlist>
<para>Bear in mind that FreeMarker distinguishes strings from
numbers and booleans, so the string <literal>"150"</literal> and the
number <literal>150</literal> are totally different. A number holds
a numerical value. A boolean holds a logical true or false. A string
holds an arbitrary sequence of characters.</para>
</section>
<section xml:id="dgui_datamodel_container">
<title>Containers</title>
<remark>Re-explanation of hashes and sequences from a more
''professional'' viewpoint as earlier, and some meditation about
them.</remark>
<para>These are the values whose purpose is to contain other
variables; they are just containers. The contained variables are
often referred as <emphasis>subvariables</emphasis>. The container
types are:</para>
<itemizedlist>
<listitem>
<para><indexterm>
<primary>hash</primary>
<secondary>the FTL value type</secondary>
</indexterm>Hash: Associates a unique lookup name with each of
its subvariables. The name is an unrestricted string. A hash
<emphasis>doesn't define an ordering</emphasis> for the
subvariables in it. That is, there is no such thing as the first
subvariable, and the second subvariable, etc.; the variables are
just accessed by name.</para>
</listitem>
<listitem>
<para><indexterm>
<primary>sequence</primary>
<secondary>the FTL value type</secondary>
</indexterm>Sequence: Associates an integer number with each
of its subvariables. The first subvariable is associated with 0,
the second with 1, the third to 2, and so on; the subvariables
are ordered. These numbers are often called the
<emphasis>indexes</emphasis> of the subvariables. Sequences are
usually dense, i.e., all indexes up to the index of the last
subvariable have an associated subvariable, but it's not
strictly necessary. The type of the subvariable values need not
be the same.</para>
</listitem>
<listitem>
<para><indexterm>
<primary>collection</primary>
<secondary>the FTL value type</secondary>
</indexterm>Collection: A collection, from the viewpoint of
the template author, is a restricted sequence. You cannot access
its size or retrieve its subvariables by index, but they can be
still listed with the <link
linkend="ref.directive.list"><literal>list</literal>
directive</link>.</para>
</listitem>
</itemizedlist>
<para>Note that since <link linkend="topic.multitype">a value can
have multiple types</link>, it is possible for a value to be both a
hash and a sequence, in which case it would support index-based
access as well as access by lookup name. However, typically a
container will be either a hash or a sequence, not both.</para>
<para>As the value of the variables stored in hashes and sequences
(and collections) can be anything, it can be a hash or sequence (or
collection) as well. This way you can build arbitrarily deep
structures.</para>
<para>The data-model itself (or better said the root of it) is a
hash.</para>
</section>
<section>
<title>Subroutines</title>
<section xml:id="dgui_datamodel_method">
<title>Methods and functions</title>
<anchor xml:id="topic.designer.methodVariable"/>
<indexterm>
<primary>method</primary>
<secondary>the FTL value type</secondary>
</indexterm>
<para>A value that is a method or a function is used to calculate
another value, influenced by the parameters you give to it.</para>
<para><phrase role="forProgrammers">For programmer types:
Methods/functions are first-class values, just like in functional
programming languages. This means that functions/methods can be
the parameters or return values of other functions/methods, you
can assign them to variables, and so on.</phrase></para>
<para>Suppose that programmers have put the method variable
<literal>avg</literal> in the data-model that can be used to
calculate the average of numbers. If you give the 3 and 5 as
parameters when you access <literal>avg</literal>, then you get
the value 4.</para>
<para>The usage of methods will be explained <link
linkend="dgui_template_exp_methodcall">later</link>, but perhaps
this example helps to understand what methods are:</para>
<programlisting role="template">The average of 3 and 5 is: ${avg(3, 5)}
The average of 6 and 10 and 20 is: ${avg(6, 10, 20)}
The average of the price of a python and an elephant is:
${avg(animals.python.price, animals.elephant.price)}</programlisting>
<para>this will output:</para>
<programlisting role="output">The average of 3 and 5 is: 4
The average of 6 and 10 and 20 is: 12
The average of the price of a python and an elephant is:
4999.5</programlisting>
<para>What is the difference between a method and a function? As
far as the template author is concerned, nothing. Well not really
nothing, as methods typically come from the data-model (<phrase
role="forProgrammers">as they reflect the methods of Java
objects</phrase>), and functions are defined in templates (with
the <link
linkend="ref.directive.function"><literal>function</literal>
directive</link> -- an advanced topic), but both can be used on
the same way.</para>
</section>
<section xml:id="dgui_datamodel_userdefdir">
<title>User-defined directives</title>
<indexterm>
<primary>macro</primary>
<secondary>the FTL value type</secondary>
</indexterm>
<indexterm>
<primary>directive</primary>
<secondary>the FTL value type</secondary>
</indexterm>
<indexterm>
<primary>user-defined directive</primary>
<secondary>the FTL value type</secondary>
</indexterm>
<para>A value of this type can be used as user-defined directive
(with other words, as FreeMarker tag). An user-defined directive
is a subroutine, something like a little reusable template
fragment. But this is an advanced topic that will be explained
<link linkend="dgui_misc_userdefdir">later</link> in its own
chapter.</para>
<para><phrase role="forProgrammers">For programmer types:
user-defined directives (such as macros), are first-class values
too, just like functions/methods are.</phrase></para>
<para>Just to get an idea about user-defined directives (so just
ignore this if you won't understand), assume we have a variable,
<literal>box</literal>, whose value is a user-defined directive
that prints some kind of fancy HTML message box with a title bar
and a message in it. The <literal>box</literal> variable could be
used in the template like this (for example):</para>
<programlisting role="template">&lt;@<emphasis>box</emphasis> title="Attention!"&gt;
Too much copy-pasting may leads to
maintenance headaches.
&lt;/@<emphasis>box</emphasis>&gt;</programlisting>
</section>
<section>
<title>Function/method versus user-defined directive</title>
<para>This is for advanced users again (so ignore it if you don't
understand). It's a frequent dilemma if you should use a
function/method or an user-defined directive to implement
something. The rule of thumb is: Implement the facility as
user-defined directive instead of as function/method if:</para>
<itemizedlist>
<listitem>
<para>... the output (the return value) is markup (HTML, XML,
etc.). The main reason is that the result of functions are
subject to automatic XML-escaping (due to the nature of
<literal>${<replaceable>...</replaceable>}</literal>), while
the output of user-defined directives are not (due to the
nature of
<literal>&lt;@<replaceable>...</replaceable>&gt;</literal>;
its output is assumed to be markup, and hence already
escaped).</para>
</listitem>
<listitem>
<para>... it's the side-effect that is important and not the
return value. For example, a directive whose purpose is to add
an entry to the server log is like that. (In fact you can't
have a return value for a user-defined directive, but some
kind of feedback is still possible by setting non-local
variables.)</para>
</listitem>
<listitem>
<para>... it will do flow control (like for example
<literal>list</literal> or <literal>if</literal> directives
do). You just can't do that with a function/method
anyway.</para>
</listitem>
</itemizedlist>
<para>The Java methods of FreeMarker-unaware Java objects are
normally visible as methods in templates, regardless of the nature
of the Java method. That said, you have no choice there.</para>
</section>
</section>
<section>
<title>Miscellaneous</title>
<section xml:id="dgui_datamodel_node">
<title>Nodes</title>
<indexterm>
<primary>node</primary>
<secondary>the FTL value type</secondary>
</indexterm>
<para>Node variables represent a node in a tree structure, and are
used mostly with <link linkend="xgui">XML processing</link>, which
is an advanced, and specialized topic.</para>
<para>Still, a quick overview <emphasis>for advanced
users</emphasis>: A node is similar to a sequence that stores
other nodes, which are often referred as the children nodes. A
node stores a reference to its container node, which is often
referred as the parent node. The main point of being a node is the
topological information; other data must be stored by utilizing
that a value can have multiple types. Like, a value may be both a
node and a number, in which case it can store a number as the
"pay-load". Apart from the topological information, a node can
store some metainformation as well: a node name, a node type
(string), and a node namespace (string). For example, if the node
symbolizes a <literal>h1</literal> element in an XHTML document,
then its name could be <literal>"h1"</literal>, it's node type
could be <literal>"element"</literal>, and it's namespace could be
<literal>"http://www.w3.org/1999/xhtml"</literal>. But it's up to
the designer of the data-model if what meaning these
metainformations have, and if they are used at all. The way of
retrieving the topological and metainformations is described <link
linkend="ref_builtins_node">in a later chapter</link> (that you
don't have to understand at this point).</para>
</section>
</section>
</section>
</chapter>
<chapter xml:id="dgui_template">
<title>The Template</title>
<indexterm>
<primary>template</primary>
</indexterm>
<note>
<para>It is assumed that you have already read the <xref
linkend="dgui_quickstart"/> and the <xref linkend="dgui_datamodel"/>
chapter.</para>
</note>
<section xml:id="dgui_template_overallstructure">
<title>Overall structure</title>
<para>Templates are in fact programs you write in a language called
<indexterm>
<primary>FTL</primary>
</indexterm><emphasis role="term">FTL</emphasis> (for FreeMarker
Template Language). This is a quite simple programming language
designed for writing templates and nothing else.</para>
<para>A template (= FTL program) is a mix of the following
sections:</para>
<itemizedlist>
<listitem>
<para><emphasis role="term">Text</emphasis><indexterm>
<primary>text</primary>
</indexterm>: Text that will be printed to the output as
is.</para>
</listitem>
<listitem>
<para><emphasis role="term">Interpolation</emphasis><indexterm>
<primary>interpolation</primary>
</indexterm>: These sections will be replaced with a calculated
value in the output. Interpolations are delimited by
<literal>${</literal> and <literal>}</literal> (or with
<literal>#{</literal> and <literal>}</literal>, but that shouldn't
be used anymore; <link
linkend="ref_depr_numerical_interpolation">see more
here</link>).</para>
</listitem>
<listitem>
<para><emphasis role="term">FTL tags</emphasis><indexterm>
<primary>FTL tag</primary>
</indexterm>: FTL tags are a bit similar to HTML tags, but they
are instructions to FreeMarker and will not be printed to the
output.</para>
</listitem>
<listitem>
<para><emphasis role="term">Comments</emphasis><indexterm>
<primary>comment</primary>
</indexterm><indexterm>
<primary>&lt;#--...--&gt;</primary>
</indexterm><indexterm>
<primary>#</primary>
</indexterm>: Comments are similar to HTML comments, but they
are delimited by <literal>&lt;#--</literal> and
<literal>--&gt;</literal>. Comments will be ignored by FreeMarker,
and will not be written to the output.</para>
</listitem>
</itemizedlist>
<para>Let's see a concrete template. I have marked the template's
components with colors: <phrase role="markedText">text</phrase>,
<phrase role="markedInterpolation">interpolation</phrase>, <phrase
role="markedFTLTag">FTL tag</phrase>, <phrase
role="markedComment">comment</phrase>. With the <phrase
role="markedInvisibleText">[BR]</phrase>-s I intend to visualize the
<link linkend="gloss.lineBreak">line breaks</link>.</para>
<programlisting role="template"><phrase role="markedText">&lt;html&gt;<phrase
role="markedInvisibleText">[BR]</phrase>
&lt;head&gt;<phrase role="markedInvisibleText">[BR]</phrase>
  &lt;title&gt;Welcome!&lt;/title&gt;<phrase role="markedInvisibleText">[BR]</phrase>
&lt;/head&gt;<phrase role="markedInvisibleText">[BR]</phrase>
&lt;body&gt;<phrase role="markedInvisibleText">[BR]</phrase>
  <phrase role="markedComment">&lt;#-- Greet the user with his/her name --&gt;</phrase><phrase
role="markedInvisibleText">[BR]</phrase>
  &lt;h1&gt;Welcome <phrase role="markedInterpolation">${user}</phrase>!&lt;/h1&gt;<phrase
role="markedInvisibleText">[BR]</phrase>
  &lt;p&gt;We have these animals:<phrase role="markedInvisibleText">[BR]</phrase>
  &lt;ul&gt;<phrase role="markedInvisibleText">[BR]</phrase>
  <phrase role="markedFTLTag">&lt;#list animals as being&gt;</phrase><phrase
role="markedInvisibleText">[BR]</phrase>
    &lt;li&gt;<phrase role="markedInterpolation">${being.name}</phrase> for <phrase
role="markedInterpolation">${being.price}</phrase> Euros<phrase
role="markedInvisibleText">[BR]</phrase>
  <phrase role="markedFTLTag">&lt;/#list&gt;</phrase><phrase
role="markedInvisibleText">[BR]</phrase>
  &lt;/ul&gt;<phrase role="markedInvisibleText">[BR]</phrase>
&lt;/body&gt;<phrase role="markedInvisibleText">[BR]</phrase>
&lt;/html&gt;</phrase></programlisting>
<para>FTL distinguishes upper case and lower case letters. So
<literal>list</literal> is good directive name, while
<literal>List</literal> is not. Similarly <literal>${name}</literal>
is not the same as <literal>${Name}</literal> or
<literal>${NAME}</literal></para>
<para>It is important to realize that <phrase
role="markedInterpolation">interpolations</phrase> can be used in
<phrase role="markedText">text</phrase> (and in string literal
expressions; see <link
linkend="dgui_template_exp_stringop_interpolation">later</link>)
only.</para>
<para>An <phrase role="markedFTLTag">FTL tag</phrase> can't be inside
another <phrase role="markedFTLTag">FTL tag</phrase> nor inside an
<phrase role="markedInterpolation">interpolation</phrase>. For example
this is <emphasis>WRONG</emphasis>: <literal>&lt;#if &lt;#include
'foo'&gt;='bar'&gt;...&lt;/#if&gt;</literal></para>
<para><phrase role="markedComment">Comments</phrase> can be placed
inside <phrase role="markedFTLTag">FTL tags</phrase> and <phrase
role="markedInterpolation">interpolations</phrase>. For
example:</para>
<programlisting role="template"><phrase role="markedText">&lt;h1&gt;Welcome <phrase
role="markedInterpolation">${user <phrase role="markedComment">&lt;#-- The name of user --&gt;</phrase>}</phrase>!&lt;/h1&gt;<phrase
role="markedInvisibleText">[BR]</phrase>
&lt;p&gt;We have these animals:<phrase role="markedInvisibleText">[BR]</phrase>
&lt;ul&gt;<phrase role="markedInvisibleText">[BR]</phrase>
<phrase role="markedFTLTag">&lt;#list <phrase role="markedComment">&lt;#-- some comment... --&gt;</phrase> animals as <phrase
role="markedComment">&lt;#-- again... --&gt;</phrase> being&gt;</phrase><phrase
role="markedInvisibleText">[BR]</phrase></phrase>
<replaceable>...</replaceable></programlisting>
<note>
<para>For those of you who have tried the above examples: You may
notice that some of spaces, tabs and line breaks are missing from
the template output, even though we said that <phrase
role="markedText">text</phrase> is printed as is. Don't bother with
it now. This is because the feature called ''white-space stripping''
is turned on, and that automatically removes some superfluous
spaces, tabs and line breaks. This will be explained <link
linkend="dgui_misc_whitespace">later</link>.</para>
</note>
</section>
<section xml:id="dgui_template_directives">
<title>Directives</title>
<indexterm>
<primary>&lt;#...&gt;</primary>
</indexterm>
<indexterm>
<primary>#</primary>
</indexterm>
<anchor xml:id="term.designer.directive"/>
<remark>Note that the Expressions chapter depends on this chapter, and
Interpolations chapter depends on Expressions chapter. Thus Directives
must be the first chapter after Basics.</remark>
<para><indexterm>
<primary>directive</primary>
</indexterm>You use FTL tags to call <emphasis
role="term">directives</emphasis>. In the example you have called the
<literal>list</literal> directive. Syntactically you have done it with
two tags: <literal>&lt;#list animals as being&gt;</literal> and
<literal>&lt;/#list&gt;</literal>.</para>
<para><indexterm>
<primary>FTL tag</primary>
</indexterm>There are two kind of FTL tags:</para>
<itemizedlist>
<listitem>
<para>Start-tag:
<literal>&lt;#<replaceable>directivename</replaceable>
<replaceable>parameters</replaceable>&gt;</literal></para>
</listitem>
<listitem>
<para>End-tag:
<literal>&lt;/#<replaceable>directivename</replaceable>&gt;</literal></para>
</listitem>
</itemizedlist>
<para>This is similar to HTML or XML syntax, except that the tag name
starts with <literal>#</literal>. If the directive doesn't have nested
content (content between the start-tag and the end-tag), you must use
the start-tag with no end-tag. For example you write <literal>&lt;#if
<replaceable>something</replaceable>&gt;<replaceable>...</replaceable>&lt;/#if&gt;</literal>,
but just <literal>&lt;#include
<replaceable>something</replaceable>&gt;</literal> as FreeMarker knows
that the <literal>include</literal> directive can't have nested
content.</para>
<para>The format of the
<literal><replaceable>parameters</replaceable></literal> depends on
the
<literal><replaceable>directivename</replaceable></literal>.</para>
<para>In fact there are two types of directives: <link
linkend="gloss.predefinedDirective">predefined directives</link> and
<link linkend="gloss.userDefinedDirective">user-defined
directives</link>. For user-defined directives you use
<literal>@</literal> instead of <literal>#</literal>, for example
<literal>&lt;@mydirective
<replaceable>parameters</replaceable>&gt;<replaceable>...</replaceable>&lt;/@mydirective&gt;</literal>.
Further difference is that if the directive has no nested content, you
must use a tag like <literal>&lt;@mydirective
<replaceable>parameters</replaceable> /&gt;</literal>, similarly as in
XML (e.g. <literal>&lt;img <replaceable>...</replaceable>
/&gt;</literal>). But user-defined directives is an advanced topic
that will be discussed <link
linkend="dgui_misc_userdefdir">later</link>.</para>
<para>FTL tags, like HTML tags, must be properly nested. So the code
below is wrong, as the <literal>if</literal> directive is both inside
and outside of the nested content of the <literal>list</literal>
directive:</para>
<programlisting role="template">&lt;ul&gt;
<emphasis>&lt;#list animals as being&gt;</emphasis>
&lt;li&gt;${being.name} for ${being.price} Euros
<emphasis>&lt;#if user == "Big Joe"&gt;</emphasis>
(except for you)
<emphasis>&lt;/#list&gt;</emphasis> &lt;#-- WRONG! The "if" has to be closed first. --&gt;
<emphasis>&lt;/#if&gt;</emphasis>
&lt;/ul&gt;</programlisting>
<para>Note that FreeMarker doesn't care about the nesting of HTML
tags, only about the nesting of FTL tags. It just sees HTML as flat
text, it doesn't interpret it in any way.</para>
<para>If you try to use a non-existing directive (e.g., you mistype
the directive name), FreeMarker will decline to use the template and
produce an error message.</para>
<para>FreeMarker ignores superfluous <link
linkend="gloss.whiteSpace">white-space</link> inside FTL tags. So you
can write this:</para>
<programlisting role="template"><phrase role="markedText"><phrase
role="markedFTLTag">&lt;#list<phrase role="markedInvisibleText">[BR]</phrase>
  animals       as<phrase role="markedInvisibleText">[BR]</phrase>
     being<phrase role="markedInvisibleText">[BR]</phrase>
&gt;</phrase><phrase role="markedInvisibleText">[BR]</phrase>
<phrase role="markedInterpolation">${being.name}</phrase> for <phrase
role="markedInterpolation">${being.price}</phrase> Euros<phrase
role="markedInvisibleText">[BR]</phrase>
<phrase role="markedFTLTag">&lt;/#list    &gt;</phrase></phrase></programlisting>
<para>You may not, however, insert white-space between the
<literal>&lt;</literal> or <literal>&lt;/</literal> and the directive
name.</para>
<para>The complete list and description of all directives can be found
in the <xref linkend="ref_directives"/> (but I recommend that you look
at the chapter about expressions first).</para>
<note>
<para>FreeMarker can be configured to use <literal>[</literal> and
<literal>]</literal> instead of <literal>&lt;</literal> and
<literal>&gt;</literal> in the FTL tags and FTL comments, like
<literal>[#if user == "Big
Joe"]<replaceable>...</replaceable>[/#if]</literal>. For more
information read: <xref
linkend="dgui_misc_alternativesyntax"/>.</para>
</note>
<note>
<para>FreeMarker can be configured so that it understands predefined
directives without <literal>#</literal> (like <literal>&lt;if user
== "Big
Joe"&gt;<replaceable>...</replaceable>&lt;/if&gt;</literal>).
However we don't recommend the usage of this mode. For more
information read: <xref linkend="ref_depr_oldsyntax"/></para>
</note>
</section>
<section xml:id="dgui_template_exp">
<title>Expressions</title>
<para><indexterm>
<primary>expression</primary>
</indexterm>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 <literal>(x +
y)/2</literal> resolves to the numerical value 6.5.</para>
<para>Before we go into details, let's see some concrete
examples:</para>
<itemizedlist>
<listitem>
<para>When you supply value for interpolations: The usage of
interpolations is
<literal>${<replaceable>expression</replaceable>}</literal> where
expression gives the value you want to insert into the output as
text. So <literal>${(5 + 8)/2}</literal> prints ``6.5'' to the
output (or possibly ``6,5'' if the language of your output is not
US English).</para>
</listitem>
<listitem>
<para>When you supply a value for the directive parameter: You
have already seen the <literal>if</literal> directive in the
Getting Started section. The syntax of this directive is:
<literal>&lt;#if
<replaceable>expression</replaceable>&gt;<replaceable>...</replaceable>&lt;/#if&gt;</literal>.
The expression here must evaluate to a boolean value. For example
in <literal>&lt;#if 2 &lt; 3&gt;</literal> the <literal>2 &lt;
3</literal> (2 is less than 3) is an expression which evaluates to
<literal>true</literal>.</para>
</listitem>
</itemizedlist>
<section xml:id="exp_cheatsheet">
<title>Quick overview (cheat sheet)</title>
<para>This is a reminder for those of you who already know
FreeMarker or are just experienced programmers:</para>
<itemizedlist spacing="compact">
<listitem>
<para><link linkend="dgui_template_exp_direct">Specify values
directly</link></para>
<itemizedlist spacing="compact">
<listitem>
<para><link
linkend="dgui_template_exp_direct_string">Strings</link>:
<literal>"Foo"</literal> or <literal>'Foo'</literal> or
<literal>"It's \"quoted\""</literal> or
<literal>r"C:\raw\string"</literal></para>
</listitem>
<listitem>
<para><link
linkend="dgui_template_exp_direct_number">Numbers</link>:
<literal>123.45</literal></para>
</listitem>
<listitem>
<para><link
linkend="dgui_template_exp_direct_boolean">Booleans</link>:
<literal>true</literal>, <literal>false</literal></para>
</listitem>
<listitem>
<para><link
linkend="dgui_template_exp_direct_seuqence">Sequences</link>:
<literal>["foo", "bar", 123.45]</literal>,
<literal>1..100</literal></para>
</listitem>
<listitem>
<para><link
linkend="dgui_template_exp_direct_hash">Hashes</link>:
<literal>{"name":"green mouse",
"price":150}</literal></para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><link linkend="dgui_template_exp_var">Retrieving
variables</link></para>
<itemizedlist spacing="compact">
<listitem>
<para><link
linkend="dgui_template_exp_var_toplevel">Top-level
variables</link>: <literal>user</literal></para>
</listitem>
<listitem>
<para><link linkend="dgui_template_exp_var_hash">Retrieving
data from a hash</link>: <literal>user.name</literal>,
<literal>user["name"]</literal></para>
</listitem>
<listitem>
<para><link
linkend="dgui_template_exp_var_sequence">Retrieving data
from a sequence</link>:
<literal>products[5]</literal></para>
</listitem>
<listitem>
<para><link linkend="dgui_template_exp_var_special">Special
variable</link>: <literal>.main</literal></para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><link linkend="dgui_template_exp_stringop">String
operations</link></para>
<itemizedlist spacing="compact">
<listitem>
<para><link
linkend="dgui_template_exp_stringop_interpolation">Interpolation
(or concatenation)</link>:
<literal>"Hello ${user}!"</literal> (or
<literal>"Free" + "Marker"</literal>)</para>
</listitem>
<listitem>
<para><link
linkend="dgui_template_exp_get_character">Getting a
character</link>: <literal>name[0]</literal></para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><link linkend="dgui_template_exp_sequenceop">Sequence
operations</link></para>
<itemizedlist spacing="compact">
<listitem>
<para><link
linkend="dgui_template_exp_sequenceop_cat">Concatenation</link>:
<literal>users + ["guest"]</literal></para>
</listitem>
<listitem>
<para><link
linkend="dgui_template_exp_seqenceop_slice">Sequence
slice</link>: <literal>products[10..19]</literal> or
<literal>products[5..]</literal></para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><link linkend="dgui_template_exp_hashop">Hash
operations</link></para>
<itemizedlist spacing="compact">
<listitem>
<para><link
linkend="dgui_template_exp_hashop_cat">Concatenation</link>:
<literal>passwords + {"joe":"secret42"}</literal></para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><link linkend="dgui_template_exp_arit">Arithmetical
calculations</link>: <literal>(x * 1.5 + 10) / 2 - y %
100</literal></para>
</listitem>
<listitem>
<para><link
linkend="dgui_template_exp_comparison">Comparison</link>:
<literal>x == y</literal>, <literal>x != y</literal>,
<literal>x &lt; y</literal>, <literal>x &gt; y</literal>,
<literal>x &gt;= y</literal>, <literal>x &lt;= y</literal>,
<literal>x &amp;lt; y</literal>, ...etc.</para>
</listitem>
<listitem>
<para><link linkend="dgui_template_exp_logicalop">Logical
operations</link>: <literal>!registered &amp;&amp; (firstVisit
|| fromEurope)</literal></para>
</listitem>
<listitem>
<para><link
linkend="dgui_template_exp_builtin">Built-ins</link>:
<literal>name?upper_case</literal></para>
</listitem>
<listitem>
<para><link linkend="dgui_template_exp_methodcall">Method
call</link>: <literal>repeat("What", 3)</literal></para>
</listitem>
<listitem>
<para><link linkend="dgui_template_exp_missing">Missing value
handler operators</link>:</para>
<itemizedlist spacing="compact">
<listitem>
<para><link
linkend="dgui_template_exp_missing_default">Default
value</link>: <literal>name!"unknown"</literal> or
<literal>(user.name)!"unknown"</literal> or
<literal>name!</literal> or
<literal>(user.name)!</literal></para>
</listitem>
<listitem>
<para><link linkend="dgui_template_exp_missing_test">Missing
value test</link>: <literal>name??</literal> or
<literal>(user.name)??</literal></para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<para>See also: <link
linkend="dgui_template_exp_precedence">Operator
precedence</link></para>
</section>
<section xml:id="dgui_template_exp_direct">
<title>Specify values directly</title>
<indexterm>
<primary>literal</primary>
</indexterm>
<indexterm>
<primary>constant</primary>
</indexterm>
<para>Often you want to specify a value directly and not as a result
of some calculations.</para>
<section xml:id="dgui_template_exp_direct_string">
<title>Strings</title>
<indexterm>
<primary>string</primary>
<secondary>literal</secondary>
</indexterm>
<para>To specify a string value directly you give the text in
quotation marks, e.g.: <literal>"some text"</literal> or in
apostrophe-quote, e.g. <literal>'some text'</literal>. The two
forms are equivalent. If the text itself contains the character
used for the quoting (either <literal>"</literal> or
<literal>'</literal>) or backslashes, you have to precede them
with a backslash; this is called escaping. You can type any other
character, including <link linkend="gloss.lineBreak">line
breaks</link>, in the text directly. Example:</para>
<programlisting role="template">${"It's \"quoted\" and
this is a backslash: \\"}
${'It\'s "quoted" and
this is a backslash: \\'}</programlisting>
<para>will print:</para>
<programlisting role="output">It's "quoted" and
this is a backslash: \
It's "quoted" and
this is a backslash: \</programlisting>
<note>
<para>Of course, you could simply type the above text into the
template, without using
<literal>${<replaceable>...</replaceable>}</literal>. But we do
it here just for the sake of example, to demonstrate
expressions.</para>
</note>
<anchor xml:id="topic.escapeSequence"/>
<indexterm>
<primary>escape sequences</primary>
</indexterm>
<para>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.</para>
<informaltable border="1">
<thead>
<tr>
<th>Escape sequence</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><literal>\"</literal></td>
<td>Quotation mark (u0022)</td>
</tr>
<tr>
<td><literal>\'</literal></td>
<td>Apostrophe (a.k.a. apostrophe-quote) (u0027)</td>
</tr>
<tr>
<td><literal>\\</literal></td>
<td>Back slash (u005C)</td>
</tr>
<tr>
<td><literal>\n</literal></td>
<td>Line feed (u000A)</td>
</tr>
<tr>
<td><literal>\r</literal></td>
<td>Carriage return (u000D)</td>
</tr>
<tr>
<td><literal>\t</literal></td>
<td>Horizontal tabulation (a.k.a. tab) (u0009)</td>
</tr>
<tr>
<td><literal>\b</literal></td>
<td>Backspace (u0008)</td>
</tr>
<tr>
<td><literal>\f</literal></td>
<td>Form feed (u000C)</td>
</tr>
<tr>
<td><literal>\l</literal></td>
<td>Less-than sign: <literal>&lt;</literal></td>
</tr>
<tr>
<td><literal>\g</literal></td>
<td>Greater-than sign: <literal>&gt;</literal></td>
</tr>
<tr>
<td><literal>\a</literal></td>
<td>Ampersand: <literal>&amp;</literal></td>
</tr>
<tr>
<td><literal>\x<replaceable>Code</replaceable></literal></td>
<td>Character given with its hexadecimal <link
linkend="gloss.unicode">Unicode</link> code (<link
linkend="gloss.UCS">UCS</link> code)</td>
</tr>
</tbody>
</informaltable>
<para>The <literal><replaceable>Code</replaceable></literal> after
the <literal>\x</literal> is 1 to 4 hexadecimal digits. For
example this all put a copyright sign into the string:
<literal>"\xA9 1999-2001"</literal>,
<literal>"\x0A9 1999-2001"</literal>,
<literal>"\x00A9 1999-2001"</literal>. 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 be
confused.</para>
<para>Note that the character sequence <literal>${</literal> (and
<literal>#{</literal>) has special meaning. It's used to insert
the value of expressions (typically: the value of variables, as in
<literal>"Hello ${user}!"</literal>). This will be explained <link
linkend="dgui_template_exp_stringop_interpolation">later</link>.
If you want to print <literal>${</literal>, you should use raw
string literals as explained below.</para>
<indexterm>
<primary>raw string literal</primary>
</indexterm>
<para>A special kind of string literals is the raw string
literals. In raw string literals, backslash and
<literal>${</literal> 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 <literal>r</literal> directly
before the opening quotation mark or apostrophe-quote.
Example:</para>
<programlisting role="template">${r"${foo}"}
${r"C:\foo\bar"}</programlisting>
<para>will print:</para>
<programlisting role="output">${foo}
C:\foo\bar</programlisting>
</section>
<section xml:id="dgui_template_exp_direct_number">
<title>Numbers</title>
<indexterm>
<primary>number</primary>
<secondary>literal</secondary>
</indexterm>
<para>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 <literal>-</literal> or <literal>+</literal> to indicate the
sign (<literal>+</literal> is redundant). Scientific notation is
not yet supported (so <literal>1E3</literal> is wrong). Also, you
cannot omit the 0 before the decimal separator (so
<literal>.5</literal> is wrong).</para>
<para>Examples of valid number literals: <literal>0.08</literal>,
<literal>-5.013</literal>, <literal>8</literal>,
<literal>008</literal>, <literal>11</literal>,
<literal>+11</literal></para>
<para>Note that numerical literals like <literal>08</literal>,
<literal>+8</literal>, <literal>8.00</literal> and
<literal>8</literal> are totally equivalent as they all symbolize
the number eight. Thus, <literal>${08}</literal>,
<literal>${+8}</literal>, <literal>${8.00}</literal> and
<literal>${8}</literal> will all print exactly same.</para>
</section>
<section xml:id="dgui_template_exp_direct_boolean">
<title>Booleans</title>
<indexterm>
<primary>boolean</primary>
<secondary>literal</secondary>
</indexterm>
<indexterm>
<primary>literal</primary>
<secondary>boolean</secondary>
</indexterm>
<para>To specify a boolean value you write <literal>true</literal>
or <literal>false</literal>. Don't use quotation marks.</para>
</section>
<section xml:id="dgui_template_exp_direct_seuqence">
<title>Sequences</title>
<indexterm>
<primary>sequence</primary>
<secondary>literal</secondary>
</indexterm>
<indexterm>
<primary>numerical sequence</primary>
</indexterm>
<indexterm>
<primary>numerical range expression</primary>
</indexterm>
<indexterm>
<primary>range expression</primary>
</indexterm>
<para>To specify a literal sequence, you list the <link
linkend="topic.dataModel.subVar">subvariables</link> separated by
commas, and put the whole list into square brackets. For
example:</para>
<programlisting role="template">&lt;#list <emphasis>["winter", "spring", "summer", "autumn"]</emphasis> as x&gt;
${x}
&lt;/#list&gt;</programlisting>
<para>will print:</para>
<programlisting role="output">winter
spring
summer
autumn
</programlisting>
<para>The items in the list are expressions, so you can do this
for example: <literal>[2 + 2, [1, 2, 3, 4], "whatnot"]</literal>.
Here the first subvariable will be the number 4, the second will
be another sequence, and the third subvariable will be the string
"whatnot".</para>
<para>You can define sequences that store a numerical range with
<literal><replaceable>start</replaceable>..<replaceable>end</replaceable></literal>,
where <literal><replaceable>start</replaceable></literal> and
<literal><replaceable>end</replaceable></literal> are expressions
that resolve to numerical values. For example
<literal>2..5</literal> is the same as <literal>[2, 3, 4,
5]</literal>, but the former is much more efficient (occupies less
memory and faster). Note that the square brackets are missing. You
can define decreasing numerical ranges too, e.g.:
<literal>5..2</literal>. (Furthermore, you can omit the
<literal><replaceable>end</replaceable></literal>, for example
<literal>5..</literal>, in which case the sequence will contain 5,
6, 7, 8, ...etc up to the infinity.)</para>
</section>
<section xml:id="dgui_template_exp_direct_hash">
<title>Hashes</title>
<indexterm>
<primary>hash</primary>
<secondary>literal</secondary>
</indexterm>
<indexterm>
<primary>literal</primary>
<secondary>hash</secondary>
</indexterm>
<para>To specify a hash in a template, you list the key/value
pairs separated by commas, and put the list into curly brackets.
The key and value within a key/value pair are separated with a
colon. Here is an example: <literal>{"name":"green mouse",
"price":150}</literal>. Note that both the names and the values
are expressions. However, the lookup names must be strings.</para>
</section>
</section>
<section xml:id="dgui_template_exp_var">
<title>Retrieving variables</title>
<section xml:id="dgui_template_exp_var_toplevel">
<title>Top-level variables</title>
<indexterm>
<primary>subvariable</primary>
<secondary>accessing</secondary>
</indexterm>
<para>To access a top-level variable, you simply use the variable
name. For example, the expression <literal>user</literal> will
evaluate to the value of variable stored with name ``user'' in the
root. So this will print what you store there:</para>
<programlisting role="template">${user}</programlisting>
<para>If there is no such top-level variable, then an error will
result when FreeMarker tries to evaluate the expression, and it
aborts template processing (unless programmers has configured
FreeMarker differently).</para>
<para>In this expression the variable name can contain only
letters (including non-Latin letters), digits (including non-Latin
digits), underline (_), dollar ($), at sign (@) and hash (#).
Furthermore, the name must not start with digit.</para>
</section>
<section xml:id="dgui_template_exp_var_hash">
<title>Retrieving data from a hash</title>
<indexterm>
<primary>subvariable</primary>
<secondary>accessing</secondary>
</indexterm>
<indexterm>
<primary>hash</primary>
<secondary>accessing subvariable</secondary>
</indexterm>
<para>If we already have a hash as a result of an expression, then
we can get its subvariable with a dot and the name of the
subvariable. Assume that we have this data-model:</para>
<programlisting role="dataModel">(root)
|
+- book
| |
| +- title = "Breeding green mouses"
| |
| +- author
| |
| +- name = "Julia Smith"
| |
| +- info = "Biologist, 1923-1985, Canada"
|
+- test = "title"</programlisting>
<para>Now we can read the <literal>title</literal> with
<literal>book.title</literal>, since the book expression will
return a hash (as explained in the last chapter). Applying this
logic further, we can read the name of the author with this
expression: <literal>book.author.name</literal>.</para>
<para>There is an alternative syntax if we want to specify the
subvariable name with an expression:
<literal>book["title"]</literal>. In the square brackets you can
give any expression as long as it evaluates to a string. So with
this data-model you can also read the title with
<literal>book[test]</literal>. More examples; these are all
equivalent: <literal>book.author.name</literal>,
<literal>book["author"].name</literal>,
<literal>book.author.["name"]</literal>,
<literal>book["author"]["name"]</literal>.</para>
<para>When you use the dot syntax, the same restrictions apply
regarding the variable name as with top-level variables (name can
contain only letters, digits, _, $, @, etc.). There are no such
restrictions when you use the square bracket syntax, since the
name is the result of an arbitrary expression. (Note, that to help
the FreeMarker XML support, if the subvariable name is
<literal>*</literal> (asterisk) or <literal>**</literal>, then you
do not have to use square bracket syntax.)</para>
<para>As with the top-level variables, trying to access a
non-existent subvariable causes an error and aborts the processing
of the template (unless programmers has configured FreeMarker
differently).</para>
</section>
<section xml:id="dgui_template_exp_var_sequence">
<title>Retrieving data from a sequence</title>
<indexterm>
<primary>subvariable</primary>
<secondary>accessing</secondary>
</indexterm>
<indexterm>
<primary>sequence</primary>
<secondary>accessing subvariable</secondary>
</indexterm>
<para>This is the same as for hashes, but you can use the square
bracket syntax only, and the expression in the brackets must
evaluate to a number, not a string. For example to get the name of
the first animal of the <link
linkend="example.stdDataModel">example data-model</link> (remember
that the number of the first item is 0, not 1):
<literal>animals[0].name</literal></para>
</section>
<section xml:id="dgui_template_exp_var_special">
<title>Special variables</title>
<indexterm>
<primary>special variables</primary>
</indexterm>
<para>Special variables are variables defined by the FreeMarker
engine itself. To access them, you use the
<literal>.<replaceable>variable_name</replaceable></literal>
syntax.</para>
<para>Normally you don't need to use special variables. They are
for expert users. The complete list of special variables can be
found in the <link linkend="ref_specvar">reference</link>.</para>
</section>
</section>
<section xml:id="dgui_template_exp_stringop">
<title>String operations</title>
<indexterm>
<primary>string</primary>
<secondary>operations</secondary>
</indexterm>
<section xml:id="dgui_template_exp_stringop_interpolation">
<title>Interpolation (or concatenation)</title>
<indexterm>
<primary>interpolation</primary>
</indexterm>
<indexterm>
<primary>concatenate strings</primary>
</indexterm>
<indexterm>
<primary>joining strings</primary>
</indexterm>
<indexterm>
<primary>string</primary>
<secondary>concatenate</secondary>
</indexterm>
<indexterm>
<primary>string</primary>
<secondary>interpolation</secondary>
</indexterm>
<indexterm>
<primary>adding strings</primary>
</indexterm>
<para>If you want to insert the value of an expression into a
string, you can use
<literal>${<replaceable>...</replaceable>}</literal> (and
<literal>#{<replaceable>...</replaceable>}</literal>) in string
literals. <literal>${<replaceable>...</replaceable>}</literal>
behaves similarly as in <phrase role="markedText">text</phrase>
sections. For example (assume that user is ``Big Joe''):</para>
<programlisting role="template">${"Hello ${user}!"}
${"${user}${user}${user}${user}"}</programlisting>
<para>will print:</para>
<programlisting role="output">Hello Big Joe!
Big JoeBig JoeBig JoeBig Joe</programlisting>
<para>Alternatively, you can use the <literal>+</literal> operator
to achieve similar result. This is the old method, and it is
called string concatenation. Example:</para>
<programlisting role="template">${"Hello " + user + "!"}
${user + user + user + user}</programlisting>
<para>This will print the same as the example with the
<literal>${<replaceable>...</replaceable>}</literal>-s.</para>
<warning>
<para>A frequent mistake of users is the usage of interpolations
in places where it shouldn't/can't be used. Interpolations work
<emphasis>only</emphasis> in <link
linkend="dgui_template_overallstructure"><phrase
role="markedText">text</phrase> sections</link> (e.g.
<literal>&lt;h1&gt;Hello ${name}!&lt;/h1&gt;</literal>) and in
string literals (e.g. <literal>&lt;#include
"/footer/${company}.html"&gt;</literal>). A typical bad usage is
<literal>&lt;#if ${isBig}&gt;Wow!&lt;/#if&gt;</literal>, which
is syntactically <emphasis>WRONG</emphasis>. You should simply
write <literal>&lt;#if isBig&gt;Wow!&lt;/#if&gt;</literal>.
Also, <literal>&lt;#if "${isBig}"&gt;Wow!&lt;/#if&gt;</literal>
is <emphasis>WRONG</emphasis> too, since the parameter value
will be a string, and the <literal>if</literal> directive wants
a boolean value, so it will cause a runtime error.</para>
</warning>
</section>
<section xml:id="dgui_template_exp_get_character">
<title>Getting a character</title>
<indexterm>
<primary>charAt</primary>
</indexterm>
<indexterm>
<primary>get character</primary>
</indexterm>
<para>You can get a single character of a string at a given index
similarly as you can <link
linkend="dgui_template_exp_var_sequence">read the subvariable of a
sequence</link>, e.g. <literal>user[0]</literal>. The result will
be a string whose length is 1; FTL doesn't have a separate
character type. As with sequence subvariables, the index must be a
number that is at least 0 and less than the length of the string,
or else an error will abort the template processing.</para>
<para>Since the sequence subvariable syntax and the character
getter syntax clashes, you can use the character getter syntax
only if the variable is not a sequence as well (which is possible
because FTL supports multi-typed values), since in that case the
sequence behavior prevails. (To work this around, you can use
<link linkend="ref_builtin_string_for_string">the
<literal>string</literal> built-in</link>, e.g.
<literal>user?string[0]</literal>. Don't worry if you don't
understand this yet; built-ins will be discussed later.)</para>
<para>Example (assume that user is ``Big Joe''):</para>
<programlisting role="template">${user[0]}
${user[4]}</programlisting>
<para>will print (note that the index of the first character is
0):</para>
<programlisting role="output">B
J
</programlisting>
<note>
<para>You can get a range of characters in the same way as you
<link linkend="dgui_template_exp_seqenceop_slice">get a sequence
slice</link>, e.g <literal>${user[1..4]}</literal> and
<literal>${user[4..]}</literal>. However, it's now depreacted to
utilize this, and instead you should use <link
linkend="ref_builtin_substring">the <literal>substring</literal>
built-in</link>; built-ins will be discussed later.</para>
</note>
</section>
</section>
<section xml:id="dgui_template_exp_sequenceop">
<title>Sequence operations</title>
<indexterm>
<primary>sequence</primary>
<secondary>operations</secondary>
</indexterm>
<section xml:id="dgui_template_exp_sequenceop_cat">
<title>Concatenation</title>
<indexterm>
<primary>concatenate sequences</primary>
</indexterm>
<indexterm>
<primary>joining sequences</primary>
</indexterm>
<indexterm>
<primary>sequence</primary>
<secondary>concatenate</secondary>
</indexterm>
<indexterm>
<primary>adding sequences</primary>
</indexterm>
<para>You can concatenate sequences in the same way as strings,
with <literal>+</literal>. Example:</para>
<programlisting role="template">&lt;#list ["Joe", "Fred"] + ["Julia", "Kate"] as user&gt;
- ${user}
&lt;/#list&gt;</programlisting>
<para>will print:</para>
<programlisting role="output">- Joe
- Fred
- Julia
- Kate
</programlisting>
<para>Note that sequence concatenation is not to be used for many
repeated concatenations, like for appending items to a sequence
inside a loop. It's just for things like <literal>&lt;#list users
+ admins as person&gt;</literal>. Although concatenating sequences
is fast and its speed is independently of the size of the
concatenated sequences, the resulting sequence will be always a
little bit slower to read than the original two sequences were.
This way the result of many repeated concatenations is a sequence
that is slow to read.</para>
</section>
<section xml:id="dgui_template_exp_seqenceop_slice">
<title>Sequence slice</title>
<indexterm>
<primary>sequence slice</primary>
</indexterm>
<indexterm>
<primary>sequence</primary>
<secondary>slice</secondary>
</indexterm>
<indexterm>
<primary>subsequence</primary>
</indexterm>
<para>With
<literal>[<replaceable>firstindex</replaceable>..<replaceable>lastindex</replaceable>]</literal>
you can get a slice of a sequence, where
<literal><replaceable>firstindex</replaceable></literal> and
<literal><replaceable>lastindex</replaceable></literal> are
expressions evaluate to number. For example, if
<literal>seq</literal> stores the sequence <literal>"a"</literal>,
<literal>"b"</literal>, <literal>"c"</literal>,
<literal>"d"</literal>, <literal>"e"</literal>,
<literal>"f"</literal> then the expression
<literal>seq[1..4]</literal> will evaluate to a sequence that
contains <literal>"b"</literal>, <literal>"c"</literal>,
<literal>"d"</literal>, <literal>"e"</literal> (since the item at
index 1 is <literal>"b"</literal>, and the item at index 4 is
<literal>"e"</literal>).</para>
<para>The <literal><replaceable>lastindex</replaceable></literal>
can be omitted, in which case it defaults to the index of the last
item of the sequence. For example, if <literal>seq</literal>
stores the sequence <literal>"a"</literal>,
<literal>"b"</literal>, <literal>"c"</literal>,
<literal>"d"</literal>, <literal>"e"</literal>,
<literal>"f"</literal> again, then <literal>seq[3..]</literal>
will evaluate to a sequence that contains <literal>"d"</literal>,
<literal>"e"</literal>, <literal>"f"</literal>.</para>
<note>
<para><literal><replaceable>lastindex</replaceable></literal>
can be omitted only since FreeMarker 2.3.3.</para>
</note>
<para>An attempt to access a subvariable past the last subvariable
or before the first subvariable of the sequence will cause an
error and abort the processing of the template.</para>
</section>
</section>
<section xml:id="dgui_template_exp_hashop">
<title>Hash operations</title>
<indexterm>
<primary>hash</primary>
<secondary>operations</secondary>
</indexterm>
<section xml:id="dgui_template_exp_hashop_cat">
<title>Concatenation</title>
<indexterm>
<primary>concatenate hashes</primary>
</indexterm>
<indexterm>
<primary>joining hashes</primary>
</indexterm>
<indexterm>
<primary>hash</primary>
<secondary>concatenate</secondary>
</indexterm>
<indexterm>
<primary>adding hashes</primary>
</indexterm>
<para>You can concatenate hashes in the same way as strings, with
<literal>+</literal>. If both hashes contain the same key, the
hash on the right-hand side of the <literal>+</literal> takes
precedence. Example:</para>
<programlisting role="template">&lt;#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}&gt;
- Joe is ${ages.Joe}
- Fred is ${ages.Fred}
- Julia is ${ages.Julia}
</programlisting>
<para>will print:</para>
<programlisting role="output">- Joe is 30
- Fred is 25
- Julia is 18</programlisting>
<para>Note that hash concatenation is not to be used for many
repeated concatenations, like for adding items to a hash inside a
loop. It's the same as with the <link
linkend="dgui_template_exp_sequenceop_cat">sequence
concatenation</link>.</para>
</section>
</section>
<section xml:id="dgui_template_exp_arit">
<title>Arithmetical calculations</title>
<indexterm>
<primary>arithmetic</primary>
</indexterm>
<indexterm>
<primary>math</primary>
</indexterm>
<indexterm>
<primary>addition</primary>
</indexterm>
<indexterm>
<primary>subtraction</primary>
</indexterm>
<indexterm>
<primary>division</primary>
</indexterm>
<indexterm>
<primary>modulus</primary>
</indexterm>
<para>This is the basic 4-function calculator arithmetic plus the
modulus operator. So the operators are:</para>
<itemizedlist spacing="compact">
<listitem>
<para>Addition: <literal>+</literal></para>
</listitem>
<listitem>
<para>Subtraction: <literal>-</literal></para>
</listitem>
<listitem>
<para>Multiplication: <literal>*</literal></para>
</listitem>
<listitem>
<para>Division: <literal>/</literal></para>
</listitem>
<listitem>
<para>Modulus (remainder): <literal>%</literal></para>
</listitem>
</itemizedlist>
<remark>Information about the precision?</remark>
<para>Example:</para>
<programlisting role="template">${100 - x * x}
${x / 2}
${12 % 10}</programlisting>
<para>Assuming that <literal>x</literal> is 5, it will print:</para>
<programlisting role="output">75
2.5
2</programlisting>
<para>Both operands must be expressions which evaluate to a
numerical value. So the example below will cause an error when
FreeMarker tries to evaluate it, since <literal>"5"</literal> is a
string and not the number 5:</para>
<programlisting role="template">${3 * "5"} &lt;#-- WRONG! --&gt;</programlisting>
<para>There is an exception to the above rule. The
<literal>+</literal> operator, is used to <link
linkend="dgui_template_exp_stringop_interpolation">concatenate
strings</link> as well. If on one side of <literal>+</literal> is a
string and on the other side of <literal>+</literal> is a numerical
value, then it will convert the numerical value to string (using the
format appropriate for language of the page) and then use the
<literal>+</literal> as string concatenation operator.
Example:</para>
<programlisting role="template">${3 + "5"}</programlisting>
<para>will output this:</para>
<programlisting role="output">35</programlisting>
<para>Generally, FreeMarker never converts a string to a number
automatically, but it may convert a number to a string
automatically.</para>
<para><indexterm>
<primary>integer division</primary>
</indexterm><indexterm>
<primary>integer part</primary>
</indexterm> People often want only the integer part of the result
of a division (or of other calculations). This is possible with the
<literal>int</literal> built-in. (Built-ins are explained <link
linkend="dgui_template_exp_builtin">later</link>):</para>
<programlisting role="template">${(x/2)?int}
${1.1?int}
${1.999?int}
${-1.1?int}
${-1.999?int}</programlisting>
<para>Assuming that <literal>x</literal> is 5, it will print:</para>
<programlisting role="output">2
1
1
-1
-1</programlisting>
</section>
<section xml:id="dgui_template_exp_comparison">
<title>Comparison</title>
<indexterm>
<primary>comparison operators</primary>
</indexterm>
<para>Sometimes you want to know if two values are equal or not, or
which value is the greater.</para>
<para>To show concrete examples I will use the <literal>if</literal>
directive here. The usage of <literal>if</literal> directive is:
<literal>&lt;#if
<replaceable>expression</replaceable>&gt;...&lt;/#if&gt;</literal>,
where expression must evaluate to a boolean value or else an error
will abort the processing of the template. If the value of
expression is <literal>true</literal> then the things between the
begin and end-tag will be processed, otherwise they will be
skipped.</para>
<para>To test two values for equality you use <literal>=</literal>
(or <literal>==</literal> as in Java or C; the two are absolutely
equivalent.) To test two values for inequality you use
<literal>!=</literal>. For example, assume that
<literal>user</literal> is ``Big Joe'':</para>
<programlisting role="template">&lt;#if <emphasis>user = "Big Joe"</emphasis>&gt;
It is Big Joe
&lt;/#if&gt;
&lt;#if <emphasis>user != "Big Joe"</emphasis>&gt;
It is not Big Joe
&lt;/#if&gt;</programlisting>
<para>The <literal>user = "Big Joe"</literal> expression in the
<literal>&lt;#if ...&gt;</literal> will evaluate to the boolean
<literal>true</literal>, so the above will say ``It is Big
Joe''.</para>
<para>The expressions on both sides of the <literal>=</literal> or
<literal>!=</literal> must evaluate to a scalar. Furthermore, the
two scalars must have the same type (i.e. strings can only be
compared to strings and numbers can only be compared to numbers,
etc.) or else an error will abort template processing. For example
<literal>&lt;#if 1 = "1"&gt;</literal> will cause an error. Note
that FreeMarker does exact comparison, so string comparisons are
case and white-space sensitive: <literal>"x"</literal> and
<literal>"x "</literal> and <literal>"X"</literal> are not equal
values.</para>
<para>For numerical and date values you can also use
<literal>&lt;</literal>, <literal>&lt;=</literal>,
<literal>&gt;=</literal> and <literal>&gt;</literal>. You can't use
them for strings! Example:</para>
<programlisting role="template">&lt;#if x <emphasis>&lt;=</emphasis> 12&gt;
x is less or equivalent with 12
&lt;/#if&gt;</programlisting>
<para>There is a little problem with <literal>&gt;=</literal> and
<literal>&gt;</literal>. FreeMarker interprets the
<literal>&gt;</literal> as the closing character of the FTL tag. To
prevent this, you have to put the expression into <link
linkend="dgui_template_exp_parentheses">parentheses</link>:
<literal>&lt;#if (x &gt; y)&gt;</literal>. Or, you can use
<literal>&amp;gt;</literal> and <literal>&amp;lt;</literal> on the
place of the problematic relation marks: <literal>&lt;#if x &amp;gt;
y&gt;</literal>. (Note that in general FTL does not support entity
references (those
<literal>&amp;<replaceable>...</replaceable>;</literal> things) in
FTL tags; it is just an exception with the arithmetical
comparisons.). Also, as an alternative you can use
<literal>lt</literal> instead of <literal>&lt;</literal>,
<literal>lte</literal> instead of <literal>&lt;=</literal>,
<literal>gt</literal> instead of <literal>&gt;</literal> and
<literal>gte</literal> instead of <literal>&gt;=</literal>. And, for
historical reasons FTL also understands <literal>\lt</literal>,
<literal>\lte</literal>, <literal>\gt</literal> and
<literal>\gte</literal> which are the same as the ones without the
backslash.</para>
</section>
<section xml:id="dgui_template_exp_logicalop">
<title>Logical operations</title>
<indexterm>
<primary>boolean</primary>
<secondary>operations</secondary>
</indexterm>
<indexterm>
<primary>logical operations</primary>
</indexterm>
<indexterm>
<primary>or</primary>
</indexterm>
<indexterm>
<primary>and</primary>
</indexterm>
<indexterm>
<primary>not</primary>
</indexterm>
<para>Just the usual logical operators:</para>
<itemizedlist spacing="compact">
<listitem>
<para>Logical or: <literal>||</literal></para>
</listitem>
<listitem>
<para>Logical and: <literal>&amp;&amp;</literal></para>
</listitem>
<listitem>
<para>Logical not: <literal>!</literal></para>
</listitem>
</itemizedlist>
<para>The operators will work with boolean values only. Otherwise an
error will abort the template processing.</para>
<para>Example:</para>
<programlisting role="template">&lt;#if x &lt; 12 <emphasis>&amp;&amp;</emphasis> color = "green"&gt;
We have less than 12 things, and they are green.
&lt;/#if&gt;
&lt;#if <emphasis>!</emphasis>hot&gt; &lt;#-- here hot must be a boolean --&gt;
It's not hot.
&lt;/#if&gt;</programlisting>
</section>
<section xml:id="dgui_template_exp_builtin">
<title>Built-ins</title>
<indexterm>
<primary>built-in</primary>
</indexterm>
<para>Built-ins provide, as the name suggest, certain built-in
functionality that is always available. Typically, a built-in
provides a different version of a variable, or some information
about the variable in question. The syntax for accessing a built-in
is like that of accessing a subvariable in a hash, except that you
use the question mark instead of a dot. For example, to get the
upper case version of a string:
<literal>user?upper_case</literal>.</para>
<para>You can find the complete <link linkend="ref_builtins">list of
built-ins in the Reference</link>. For now, just a few of the more
important ones:</para>
<itemizedlist>
<listitem>
<para>Built-ins to use with strings:</para>
<itemizedlist>