http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/731be2c2/src/manual/en_US/book.xml ---------------------------------------------------------------------- diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml new file mode 100644 index 0000000..c561322 --- /dev/null +++ b/src/manual/en_US/book.xml @@ -0,0 +1,37479 @@ +<?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"> + <info> + <title>FreeMarker Manual</title> + + <titleabbrev>Manual</titleabbrev> + + <productname>Freemarker 2.3.24 Preview 1</productname> + </info> + + <preface role="index.html" xml:id="preface"> + <title>What is FreeMarker?</title> + + <para>FreeMarker is a <emphasis>template engine</emphasis>: a generic tool + to generate text output (HTML web pages, e-mails, configuration files, + source code, etc.) based on templates and changing data. It's not an + application for end-users in itself, but a Java library, a component that + programmers can embed into their products.</para> + + <para>Templates are written in the FreeMarker Template Language (FTL). + It's a simple, specialized language, <emphasis>not</emphasis> a full-blown + programming language like PHP. You meant to prepare the data to display in + a real programming language, like issue database queries and do business + calculations, and then the template displays that already prepared data. + In the template you are focusing on how to present the data, and outside + the template you are focusing on what data to present.</para> + + <mediaobject> + <imageobject> + <imagedata fileref="figures/overview.png"/> + </imageobject> + </mediaobject> + + <para>This approach is often referred to as the <link + linkend="gloss.MVC">MVC (Model View Controller) pattern</link>, and is + particularly popular for dynamic Web pages. It helps in separating the Web + page designers (HTML authors) from the developers (Java programmers + usually). Designers won't face complicated logic in templates, and can + change the appearance of a page without programmers having to change or + recompile code.</para> + + <para>While FreeMarker was originally created for generating HTML pages in + MVC web application frameworks, it isn't bound to servlets or HTML or + anything Web-related. It's used in non-web application environments as + well.</para> + + <para>FreeMarker is <link + xlink:href="http://www.fsf.org/philosophy/free-sw.html">Free</link>, + released under the Apache License, Version 2.0.</para> + </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>Let's assume that you need a HTML page in a Web shop, similar to + this:</para> + + <programlisting role="output"><html> +<head> + <title>Welcome!</title> +</head> +<body> + <h1>Welcome <emphasis>John Doe</emphasis>!</h1> + <p>Our latest product: + <a href="<emphasis>products/greenmouse.html</emphasis>"><emphasis>green mouse</emphasis></a>! +</body> +</html></programlisting> + + <para>But the user name ("John Doe" 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 too. Thus you can't enter + these into the HTML directly, you can't use static HTML. Instead, you + can use a <emphasis role="term">template</emphasis> of the desired + output. The template is the same as the static HTML would be, except + that it contains some instructions to FreeMarker that makes it + dynamic:</para> + + <programlisting role="template" xml:id="example.first"><html> +<head> + <title>Welcome!</title> +</head> +<body> + <h1>Welcome <emphasis>${user}</emphasis>!</h1> + <p>Our latest product: + <a href="<emphasis>${latestProduct.url}</emphasis>"><emphasis>${latestProduct.name}</emphasis></a>! +</body> +</html></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, 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. (Of course, the + template file stored on the Web server is not changed by this; the + substitutions only appear in the Web server's response.)</para> + + <para>Note that the template doesn't contain the programming logic to + find out who the current visitor is, or to query the database to get + the latest product. The data to be displayed is prepared outside + FreeMarker, usually by parts written in some <quote>real</quote> + programming language like Java. The template author needn't know how + these values were calculated. In fact, the way these values are + calculated can be completely changed while the templates can remain + exactly the same, and also, the look of the page can be completely + changed without touching anything but the template. This separation of + presentation logic and business logic can be especially useful when + the template authors (designers) and the programmers are different + individuals, but also helps managing application complexity if they + are the same person. Keeping templates focused on presentation issues + (visual design, layout and formatting) is a key for using template + engines like FreeMarker efficiently.</para> + + <para><indexterm> + <primary>data-model</primary> + </indexterm>The totality of data that was prepared for the template + is called the <emphasis role="term">data-model</emphasis>. As far as + the template author is concerned, the data-model is a tree-like + structure (like folders and files on your hard disk), which, 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> + + <note> + <para>The above is just a visualization; the data-model is not in a + textual format, it's from Java objects. For the Java programmers, + the root is perhaps a Java object with <literal>getUser()</literal> + and <literal>getLatestProduct()</literal> methods, or maybe a Java + <literal>Map</literal> with <literal>"user"</literal> and + <literal>"latestProducts"</literal> keys. Similarly, + <literal>latestProduct</literal> is perhaps a Java Object with + <literal>getUrl()</literal> and <literal>getName()</literal> + methods.</para> + </note> + + <para>Earlier, you have picked values from this data-model, with the + <literal>user</literal> and <literal>latestProduct.name</literal> + expressions. If we go on with the analogy that the data model is like + a file system, then <quote>(root)</quote> and + <literal>latestProduct</literal> correspond to directories (folders), + and <literal>user</literal>, <literal>url</literal> and + <literal>name</literal> are files in those directories.</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 + | + +- message = "It is a test" + | + +- misc + | + +- foo = "Something"</programlisting> + + <para>The variables that act like directories (the root, + <literal>animals</literal>, <literal>mouse</literal>, + <literal>elephant</literal>, <literal>python</literal>, + <literal>misc</literal>) are called <emphasis + role="term">hashes</emphasis>. Hashes store other variables (the so + called <anchor xml:id="topic.dataModel.subVar"/><emphasis>sub + variables</emphasis>) by a lookup name (e.g., <quote>animals</quote>, + <quote>mouse</quote> or <quote>price</quote>).</para> + + <para>The variables that store a single value + (<literal>size</literal>, <literal>price</literal>, + <literal>message</literal> and <literal>foo</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>.</para> + + <para>Another important kind of variables are <emphasis + role="term">sequences</emphasis>. They store subvariables like hashes, + but here subvariables doesn't have a name, they are just items in a + list. For example, in this data-model, <literal>animals</literal> and + <literal>misc.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 + | + +- misc + | + +- 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 1st item is 0, the index of + the 2nd 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>misc.fruits</literal> (the string + <literal>"banana"</literal>) you write + <literal>misc.fruits[1]</literal>. (In practice, you usually just walk + through sequences in order, not caring about the index, but that will + be <link linkend="topic.tutorial.list">shown later</link>.)</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 in arithmetical calculations.</para> + </listitem> + + <listitem> + <para>Date-like: Either a date-time (stores a date with time of + the day), or a date (no time of day), or a time (time of day, no + date).</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/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> + + <note> + <para>There are other, more advanced value types that we don't cover + here, such as methods and directives.</para> + </note> + </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 expression inside the curly brackets. They are called + <emphasis role="term">interpolation</emphasis>s.</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><#--</literal> and <literal>--></literal>. Unlike + HTML comments, FTL comments won't get into the output (won't be + visible in the page source for the visitor), because FreeMarker + skips them.</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><table></literal> and + <literal></table></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> + + <note> + <para>You can easily try writing templates on <link + xlink:href="http://freemarker-online.kenshoo.com/">http://freemarker-online.kenshoo.com/</link></para> + </note> + + <section> + <title>Some basic directives</title> + + <para>Here we will look at some of the most commonly used directives + (<link linkend="ref_directives">but there are much + more</link>).</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 + than other users:</para> + + <programlisting role="template"><html> +<head> + <title>Welcome!</title> +</head> +<body> + <h1> + Welcome ${user}<emphasis><#if user == "Big Joe"></emphasis>, our beloved leader<emphasis></#if></emphasis>! + </h1> + <p>Our latest product: + <a href="${latestProduct.url}">${latestProduct.name}</a>! +</body> +</html></programlisting> + + <para>Here you have told FreeMarker that the <quote>, our beloved + leader</quote> 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><#if + <replaceable>condition</replaceable>></literal> and + <literal></#if></literal> tags are skipped if + <literal><replaceable>condition</replaceable></literal> is false + (the boolean value).</para> + + <para>Let's look at + <literal><replaceable>condition</replaceable></literal> more + closely: <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 <quote>Pythons are free today!</quote> if + their price is 0:</para> + + <programlisting role="template"><#if animals.python.price == <emphasis>0</emphasis>> + Pythons are free today! +</#if></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, and because the price to compare it to is number, + you get an error.</para> + + <para>This will print "Pythons are not free today!" if their price + is not 0:</para> + + <programlisting role="template"><#if animals.python.price <emphasis>!=</emphasis> 0> + Pythons are not free today! +</#if></programlisting> + + <para>As you probably guessed, <literal>!=</literal> means + <quote>not equals</quote>.</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"><#if <emphasis>animals.python.price < animals.elephant.price</emphasis>> + Pythons are cheaper than elephants today. +</#if></programlisting> + + <para>With the <literal><#else></literal> tag you can + specify what to do if the condition is false. For example:</para> + + <programlisting role="template"><#if animals.python.price < animals.elephant.price> + Pythons are cheaper than elephants today. +<emphasis><#else></emphasis> + Pythons are not cheaper than elephants today. +</#if></programlisting> + + <para>This prints <quote>Pythons are cheaper than elephants + today.</quote> if the price of python is less than the price of + elephant, or else it prints <quote>Pythons are not cheaper than + elephants today.</quote> You can refine this further by using + <literal>elseif</literal>:</para> + + <programlisting role="template"><#if animals.python.price < animals.elephant.price> + Pythons are cheaper than elephants today. +<emphasis><#elseif animals.elephant.price < animals.python.price></emphasis> + Elephants are cheaper than pythons today. +<#else> + Elephants and pythons cost the same today. +</#if></programlisting> + + <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"><#if animals.python.protected> + Pythons are protected animals! +</#if></programlisting> + </section> + + <section> + <title>The list directive</title> + + <anchor xml:id="topic.tutorial.list"/> + + <para>This is needed when you want to list something. For example + if you merge this template with the <link + linkend="example.qStart.dataModelWithSequences">data-model used + earlier to demonstrate sequences</link>:</para> + + <programlisting role="template"><p>We have these animals: +<table border=1> + <emphasis><#list animals as animal></emphasis> + <tr><td>${<emphasis>animal</emphasis>.name}<td>${<emphasis>animal</emphasis>.price} Euros + <emphasis></#list></emphasis> +</table></programlisting> + + <para>then the output will be:</para> + + <programlisting role="output"><p>We have these animals: +<table border=1> + <emphasis><tr><td>mouse<td>50 Euros + <tr><td>elephant<td>5000 Euros + <tr><td>python<td>4999 Euros</emphasis> +</table></programlisting> + + <para>The generic form of the <literal>list</literal> directive + is:<literal> <#list <replaceable>sequence</replaceable> as + <replaceable>loopVariable</replaceable>><replaceable>repeatThis</replaceable></#list></literal>. + The <literal><replaceable>repeatThis</replaceable></literal> part + will be repeated for each item in the sequence that you have + specified 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><#list + <replaceable>...</replaceable>></literal> and + <literal></#list></literal> tags.</para> + + <para>The <literal><replaceable>sequence</replaceable></literal> + can be any kind of expression, like we could list the fruits of + the example data model like this:</para> + + <programlisting role="template"><ul> +<emphasis><#list misc.fruits as fruit></emphasis> + <li>${fruit} +<emphasis></#list></emphasis> +</ul></programlisting> + + <para>The <literal>misc.fruits</literal> expression should be + familiar to you; it <link + linkend="topic.qStart.accessVariables">references a variable in + the data-model</link>.</para> + + <para>A problem with the above example is that if we happen to + have 0 fruits, it will still print an empty + <literal><ul></ul></literal> instead of just nothing. + To avoid that, you can use this form of + <literal>list</literal>:</para> + + <programlisting role="template"><#list misc.fruits> + <ul> + <emphasis> <#items as fruit></emphasis> + <li>${fruit} + <emphasis> </#items></emphasis> + </ul> +</#list></programlisting> + + <para>Here, the <literal>list</literal> directive represents the + listing as a whole, and only the part inside the + <literal>items</literal> directive is repeated for each fruit. If + we have 0 fruits, everything inside <literal>list</literal> is + skipped, hence we will not have <literal>ul</literal> tags in + case.</para> + + <para>Another frequent listing-related task: let's list the fruits + separating them with something, like comma:</para> + + <programlisting role="template"><p>Fruits: <#list misc.fruits as fruit>${fruit}<emphasis><#sep>, </emphasis></#list></programlisting> + + <programlisting role="output"><p>Fruits: orange, banana</programlisting> + + <para>The section covered by <literal>sep</literal> (which we + could be written like this too: + <literal><replaceable>...</replaceable><#sep>, + </#sep></#list></literal>) will be only executed when + there will be a next item. Hence there's no comma after the last + fruit.</para> + + <para>Here again, what's if we have 0 fruits? Just printing + <quote>Fruits:</quote> and then nothing is awkward. A + <literal>list</literal>, just like an <literal>if</literal>, can + have an <literal>else</literal>, which is executed if there were 0 + list items:</para> + + <programlisting role="template"><p>Fruits: <#list misc.fruits as fruit>${fruit}<#sep>, <emphasis><#else>None</emphasis></#list></programlisting> + + <note> + <para>As a matter of fact, this simplistic example could be + written like this, but it uses language devices that are off + topic here:</para> + + <programlisting role="template"><p>Fruits: ${fruits?join(", ", "None")}</programlisting> + </note> + + <para>All these directives (<literal>list</literal>, + <literal>items</literal>, <literal>sep</literal>, + <literal>else</literal>) can be used together:</para> + + <programlisting role="template"><#list misc.fruits> + <p>Fruits: + <ul> + <#items as fruit> + <li>${fruit}<#sep> and</#sep> + </#items> + </ul> +<#else> + <p>We have no fruits. +</#list></programlisting> + + <note> + <para>You can read more about these directives <link + linkend="ref_directive_list">in the Reference</link>.</para> + </note> + </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"><hr> +<i> +Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>, +<br> +All Rights Reserved. +</i></programlisting> + + <para>Whenever you need that file you simply insert it with the + <literal>include</literal> directive:</para> + + <programlisting role="template"><html> +<head> + <title>Test page</title> +</head> +<body> + <h1>Test page</h1> + <p>Blah blah... +<emphasis> <#include "/copyright_footer.html"></emphasis> +</body> +</html></programlisting> + + <para>and the output will be:</para> + + <programlisting role="output"><html> +<head> + <title>Test page</title> +</head> +<body> + <h1>Test page</h1> + <p>Blah blah... +<emphasis><hr> +<i> +Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>, +<br> +All Rights Reserved. +</i></emphasis> +</body> +</html></programlisting> + + <para>If you change the <literal>copyright_footer.html</literal>, + then the visitor will see the new copyright notice on all + pages.</para> + + <note> + <para>A much more powerful way of reusing snippets is using + macros, but that's an advanced topic <link + linkend="dgui_misc_userdefdir">discussed later</link>.</para> + </note> + </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 freely. For example, + here you nest <literal>if</literal> directive inside a + <literal>list</literal> directive:</para> + + <programlisting role="template"><emphasis><#list animals as animal></emphasis> + <div<emphasis><#if animal.protected></emphasis><emphasis> </emphasis>class="protected"<emphasis></#if></emphasis>> + ${animal.name} for ${animal.price} Euros + </div> +<emphasis></#list></emphasis></programlisting> + + <para>Note that since FreeMarker does not interpret text outside FTL + tags, interpolations and FTL comments, above you could use the FTL + tags inside a HTML attributes without problem.</para> + </section> + + <section> + <title>Using built-ins</title> + + <para>The so called built-ins are like subvariables (or rather like + methods, if you know that Java term) that aren't coming coming from + the data-model, but added by FreeMarker to the values. To make it + unambiguous where the subvarable comes from, to access them you have + to use <literal>?</literal> (question mark) instead of + <literal>.</literal> (dot). <anchor + xml:id="topic.commonlyUsedBuiltIns"/>Examples with some of the most + commonly used built-ins:</para> + + <itemizedlist> + <listitem> + <para><literal>user?upper_case</literal> gives the upper case + version of the value of <literal>user</literal> (like + <quote>JOHN DOE</quote> instead of <quote>John + Doe</quote>)</para> + </listitem> + + <listitem> + <para><literal>animal.name?cap_first</literal> give the + <literal>animal.name</literal> with its first letter converted + to upper case (like <quote>Mouse</quote> instead of + <quote>mouse</quote>)</para> + </listitem> + + <listitem> + <para><literal>user?length</literal> gives the number of + <emphasis>characters</emphasis> in the value of + <literal>user</literal> (8 for <quote>John Doe</quote>)</para> + </listitem> + + <listitem> + <para><literal>animals?size</literal> gives the number of + <emphasis>items</emphasis> in the <literal>animals</literal> + sequence (3 in our example data-model)</para> + </listitem> + + <listitem> + <para>If you are between <literal><#list animals as + animal></literal> and the corresponding + <literal></#list></literal> tag:</para> + + <itemizedlist> + <listitem> + <para><literal>animal?index</literal> gives the 0-based + index of <literal>animal</literal> inside + <literal>animals</literal></para> + </listitem> + + <listitem> + <para><literal>animal?counter</literal> is like + <literal>index</literal>, but gives the 1-based index</para> + </listitem> + + <listitem> + <para><literal>animal?item_parity</literal> gives the + strings <quote>odd</quote> or <quote>even</quote>, depending + on the current counter parity. This is commonly used for + coloring rows with alternating colors, like in + <literal><td + class="${animal?item_parity}Row"></literal>.</para> + </listitem> + </itemizedlist> + </listitem> + </itemizedlist> + + <para>Some built-ins require parameters to specify the behavior + more, for example:</para> + + <itemizedlist> + <listitem> + <para><literal>animal.protected?string("Y", "N")</literal> + return the string <quote>Y</quote> or <quote>N</quote> depending + on the boolean value of + <literal>animal.protected</literal>.</para> + </listitem> + + <listitem> + <para><literal>animal?item_cycle('lightRow', + 'darkRow')</literal> is the more generic variant of + <literal>item_parity</literal> from earlier.</para> + </listitem> + + <listitem> + <para><literal>fruits?join(", ")</literal>: converts the list to + a string by concatenating items, and inserting the parameter + separator between each items (like <quote>orange, + banana</quote>)</para> + </listitem> + + <listitem> + <para><literal>user?starts_with("J")</literal> gives boolean + true of false depending on if <literal>user</literal> starts + with the letter <quote>J</quote> or not.</para> + </listitem> + </itemizedlist> + + <para>Built-in applications can be chained, like + <literal>fruits?join(", ")?upper_case</literal> will first convert + the list a to a string, then converts it to upper case. (This is + just like you can chain <literal>.</literal>-s (dots) too.)</para> + + <para>You can find the <link linkend="ref_builtins">full set of + built-ins in the Reference</link>.</para> + </section> + + <section> + <title>Dealing with missing variables</title> + + <para>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 + 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>"visitor"</literal>. (When <literal>user</literal> isn't + missing, this template behaves exactly like with + <literal>${user}</literal>):</para> + + <programlisting role="template"><h1>Welcome ${user<emphasis>!"visitor"</emphasis>}!</h1></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"><#if <emphasis>user??</emphasis>><h1>Welcome ${user}!</h1></#if></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 xml:id="dgui_quickstart_template_autoescaping"> + <title>Escaping for HTML, XML and other markup</title> + + <para>Let's say the template generates HTML, and you insert values + with <literal>${<replaceable>...</replaceable>}</literal> that are + plain text (not HTML), like company names coming from a database. + Characters that has special meaning in HTML must be + <emphasis>escaped</emphasis> in such values, like if + <literal>name</literal> is <quote>Someone & Co.</quote> then + <literal>${name}</literal> should print <quote>Someone + <emphasis>&amp;</emphasis> Co.</quote>.</para> + + <para>FreeMarker automatically escapes all values printed with + <literal>${<replaceable>...</replaceable>}</literal> <emphasis>if + it's properly configured</emphasis> (that's the responsibility of + the programmers; <link + linkend="pgui_config_outputformatsautoesc">see here how</link>). The + recommended practice is using <literal>ftlh</literal> file extension + to activate HTML auto-escaping, and <literal>ftlx</literal> file + extension to activate XML auto-escaping.</para> + + <para>You can try if auto-escaping is on like + <literal>${"<"}</literal> (for HTML or XML escaping). If it's + not, and the configuration won't be adjusted, add this as the very + first line of the template:</para> + + <programlisting role="template"><#ftl output_format="HTML"></programlisting> + + <para>(Use <literal>"XML"</literal> instead of + <literal>"HTML"</literal> above if you generate XML.)</para> + + <para>If the string value to print deliberately contains markup, + auto-escaping must be prevented like + <literal>${<replaceable>value</replaceable>?no_esc}</literal>.</para> + + <para>You can find out much more about auto-escaping and output + formats <link linkend="dgui_misc_autoescaping">here...</link></para> + + <note> + <para>The kind of automatic escaping described here requires at + least FreeMarker 2.3.24. If you have to use an earlier version, + use the deprecated <link + linkend="ref_directive_escape"><literal>escape</literal> + directive</link> instead.</para> + </note> + </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"><#if cargo.weight < <emphasis>100</emphasis>>Light cargo</#if></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><#list <replaceable>...</replaceable>></literal> + sequences only. Or, the condition of <literal><#if + ...></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} <#-- uses mouse as a string --> +${mouse.age} <#-- uses mouse as a hash --> +${mouse.color} <#-- uses mouse as a hash --></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-like (date, time, or date-time)</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> + + <listitem> + <para><link linkend="dgui_datamodel_markupoutput">Markup + output</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><#if + loggedIn + ><replaceable>...</replaceable></#if></literal> or + <literal><#if price == + 0><replaceable>...</replaceable></#if></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-like value stores date/time related + data. It has three variations:</para> + + <itemizedlist> + <listitem> + <para>Date: Like April 4, 2003. Day precision, no time of + day part.</para> + </listitem> + + <listitem> + <para>Time: Like 10:19:18 PM. Millisecond precision, no date + part.</para> + </listitem> + + <listitem> + <para>Date-time (sometimes called "time stamp") as April 4, + 2003 10:19:18 PM. Both date and time, 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, a date or a time). + 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-like 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, booleans and date-like values. For example, while the + string <literal>"150"</literal> looks like the number + <literal>150</literal>, a string is still just arbitrary sequence of + characters, and you can't do arithmetic with it, can't compare it + with another number, etc.</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>sub variables</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 sub variables. The name is an unrestricted string. A hash + <emphasis>doesn't define an ordering</emphasis> for the sub + variables 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 sub variables. The first subvariable is associated with + 0, the second with 1, the third to 2, and so on; the sub + variables are ordered. These numbers are often called the + <emphasis>indexes</emphasis> of the sub variables. 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 sub variables 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"><@<emphasis>box</emphasis> title="Attention!"> + Too much copy-pasting may leads to + maintenance headaches. +</@<emphasis>box</emphasis>></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 purpose of it is generating a piece of the + output that's not just a single value, and typically involves + markup. The template language was designed for printing to the + output directly, piece by piece, as it goes though + <literal>list</literal> loops, <literal>if</literal>-s, etc. + Building up a string value in a variable then returning it is + much less convenient.</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 on the caller side (like for + example <literal>list</literal> or <literal>if</literal> + directives do). You just can't do that with a + function/method.</para> + </listitem> + + <listitem> + <para>... you are using legacy escaping via the + <literal>escape</literal> directive (instead of <link + linkend="dgui_misc_autoescaping">auto-escaping</link>), and + the result contains markup. When you print the result with + <literal>${<replaceable>...</replaceable>}</literal>, the + markup will be escaped and thus ruined, but if it's printed by + a directive call + (<literal><@<replaceable>...</replaceable>></literal>), + it won't be.</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; 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 xml:id="dgui_datamodel_markupoutput"> + <title>Markup output</title> + + <indexterm> + <primary>markup output</primary> + + <secondary>the FTL value type</secondary> + </indexterm> + + <para>This type is related to <link + linkend="dgui_misc_autoescaping">auto-escaping mechanism</link> + introduced FreeMarker 2.3.24; you can <link + linkend="dgui_misc_autoescaping_movalues">read about this type + there</link>. But in short, this is a value that stores text + that's already in the output markup format (like HTML, XML, RTF, + etc.), and hence must not be auto-escaped.</para> + + <para>Values of this type are usually produced inside the + templates (like with <link + linkend="ref_builtin_no_esc"><literal>no_esc</literal> + built-in</link> or <link linkend="ref_directive_assign">output + capturing assignments</link>), but can also be part of the + data-model. Such values in the data-model are useful for example + if you have message resources that sometimes contain the message + in HTML format, rather than in plain text. If the data-model uses + HTML markup output values for those messages instead of strings, + then the template author need not know which messages contain HTML + and which plain text, as double escaping will be avoided + automatically when the message is inserted with + <literal>${<replaceable>...</replaceable>}</literal>.</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><#--...--></primary> + </indexterm><indexterm> + <primary>#</primary> + </indexterm>: Comments are similar to HTML comments, but they + are delimited by <literal><#--</literal> and + <literal>--></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"><html><phrase + role="markedInvisibleText">[BR]</phrase> +<head><phrase role="markedInvisibleText">[BR]</phrase> +  <title>Welcome!</title><phrase role="markedInvisibleText">[BR]</phrase> +</head><phrase role="markedInvisibleText">[BR]</phrase> +<body><phrase role="markedInvisibleText">[BR]</phrase> +  <phrase role="markedComment"><#-- Greet the user with his/her name --></phrase><phrase + role="markedInvisibleText">[BR]</phrase> +  <h1>Welcome <phrase role="markedInterpolation">${user}</phrase>!</h1><phrase + role="markedInvisibleText">[BR]</phrase> +  <p>We have these animals:<phrase role="markedInvisibleText">[BR]</phrase> +  <ul><phrase role="markedInvisibleText">[BR]</phrase> +  <phrase role="markedFTLTag"><#list animals as animal></phrase><phrase + role="markedInvisibleText">[BR]</phrase> +    <li><phrase role="markedInterpolation">${animal.name}</phrase> for <phrase + role="markedInterpolation">${animal.price}</phrase> Euros<phrase + role="markedInvisibleText">[BR]</phrase> +  <phrase role="markedFTLTag"></#list></phrase><phrase + role="markedInvisibleText">[BR]</phrase> +  </ul><phrase role="markedInvisibleText">[BR]</phrase> +</body><phrase role="markedInvisibleText">[BR]</phrase> +</html></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><#if <#include + 'foo'>='bar'>...</#if></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"><h1>Welcome <phrase + role="markedInterpolation">${user <phrase role="markedComment"><#-- The name of user --></phrase>}</phrase>!</h1><phrase + role="markedInvisibleText">[BR]</phrase> +<p>We have these animals:<phrase role="markedInvisibleText">[BR]</phrase> +<ul><phrase role="markedInvisibleText">[BR]</phrase> +<phrase role="markedFTLTag"><#list <phrase role="markedComment"><#-- some comment... --></phrase> animals as <phrase + role="markedComment"><#-- again... --></phrase> animal></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><#...></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><#list animals as animal></literal> and + <literal></#list></literal>.</para> + + <para><indexterm> + <primary>FTL tag</primary> + </indexterm>There are two kind of FTL tags:</para> + + <itemizedlist> + <listitem> + <para>Start-tag: + <literal><#<replaceable>directivename</replaceable> + <replaceable>parameters</replaceable>></literal></para> + </listitem> + + <listitem> + <para>End-tag: + <literal></#<replaceable>directivename</replaceable>></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><#if + <replaceable>something</replaceable>><replaceable>...</replaceable></#if></literal>, + but just <literal><#include + <replaceable>something</replaceable>></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><@mydirective + <replaceable>parameters</replaceable>><replaceable>...</replaceable></@mydirective></literal>. + Further difference is that if the directive has no nested content, you + must use a tag like <literal><@mydirective + <replaceable>parameters</replaceable> /></literal>, similarly as in + XML (e.g. <literal><img <replaceable>...</replaceable> + /></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"><ul> +<emphasis><#list animals as animal></emphasis> + <li>${animal.name} for ${animal.price} Euros + <emphasis><#if user == "Big Joe"></emphasis> + (except for you) +<emphasis></#list></emphasis> <#-- WRONG! The "if" has to be closed first. --> +<emphasis></#if></emphasis> +</ul></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"><#list<phrase role="markedInvisibleText">[BR]</phrase> +  animals       as<phrase role="markedInvisibleText">[BR]</phrase> +     animal<phrase role="markedInvisibleText">[BR]</phrase> +></phrase><phrase role="markedInvisibleText">[BR]</phrase> +<phrase role="markedInterpolation">${animal.name}</phrase> for <phrase + role="markedInterpolation">${animal.price}</phrase> Euros<phrase + role="markedInvisibleText">[BR]</phrase> +<phrase role="markedFTLTag"></#list    ></phrase></phrase></programlisting> + + <para>You may not, however, insert white-space between the + <literal><</literal> or <literal></</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><</literal> and + <literal>></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><if user + == "Big + Joe"><replaceable>...</replaceable></if></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><#if + <replaceable>expression</replaceable>><replaceable>...</replaceable></#if></literal>. + The expression here must evaluate to a boolean value. For example + in <literal><#if 2 < 3></literal> the <literal>2 < + 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>'It\'s + "quoted"'</literal> or + <literal>r"C:\raw\string"</literal></para> + </listitem> + + <listitem> + <para><link + linkend="d
<TRUNCATED>
