http://git-wip-us.apache.org/repos/asf/incubator-freemarker-site/blob/52c070a9/builds/2.3.26-nightly/dgui_template_exp.html ---------------------------------------------------------------------- diff --git a/builds/2.3.26-nightly/dgui_template_exp.html b/builds/2.3.26-nightly/dgui_template_exp.html new file mode 100644 index 0000000..8a33c71 --- /dev/null +++ b/builds/2.3.26-nightly/dgui_template_exp.html @@ -0,0 +1,2331 @@ +<!doctype html> +<!-- Generated by FreeMarker/Docgen from DocBook --> +<html lang="en" class="page-type-section"> +<head prefix="og: http://ogp.me/ns#"> +<meta charset="utf-8"> +<title>Expressions - Apache FreeMarker Manual</title> +<meta http-equiv="X-UA-Compatible" content="IE=edge"> +<meta name="viewport" content="width=device-width,initial-scale=1"> +<meta name="format-detection" content="telephone=no"> +<meta property="og:site_name" content="Apache FreeMarker Manual"> +<meta property="og:title" content="Expressions"> +<meta property="og:locale" content="en_US"> +<meta property="og:url" content="http://freemarker.org/docs/dgui_template_exp.html"> +<link rel="canonical" href="http://freemarker.org/docs/dgui_template_exp.html"> +<link rel="icon" href="favicon.png" type="image/png"> +<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Roboto:500,700,400,300|Droid+Sans+Mono"> +<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1489402528979"> +<script> +(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ +(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), +m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) +})(window,document,'script','//www.google-analytics.com/analytics.js','ga'); +ga('create', 'UA-55420501-1', 'auto'); +ga('send', 'pageview'); +</script> +</head> +<body itemscope itemtype="https://schema.org/Code"> + <meta itemprop="url" content="http://freemarker.org/docs/"> + <meta itemprop="name" content="Apache FreeMarker Manual"> + + <!--[if lte IE 9]> + <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div> + <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://freemarker.org" role="banner"> <img itemprop="image" src="logo.png" alt="FreeMarker"> +</a><ul class="tabs"><li><a href="http://freemarker.org/">Home</a></li><li class="current"><a href="index.html">Manual</a></li><li><a class="external" href="api/index.html">Java API</a></li></ul><ul class="secondary-tabs"><li><a class="tab icon-heart" href="http://freemarker.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/browse/FREEMARKER/" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="http://freemarker.org/freemarkerdownload.html" title="Download"><span>Download</span></a></li></ul></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">Manual</a><div class="navigation-header"></div><form method="get" class="search-form" action="search-results.html"><fieldset><legend class="sr-only">Search form</legend><label for="search-field" class="sr-only">Search query</label><input id="searc h-field" name="q" type="search" class="search-input" placeholder="Search" spellcheck="false" autocorrect="off" autocomplete="off"><button type="submit" class="search-btn"><span class="sr-only">Search</span></button></fieldset></form></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">Apache FreeMarker Manual</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="dgui.html"><span itemprop="name">Template Author's Guide</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="dgui_template.html"><span itemprop="name">The Template</span></a></li><li class="step-3" item prop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="dgui_template_exp.html"><span itemprop="name">Expressions</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><li><a href="alphaidx.html">Alpha. index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="#exp_cheatsheet">Expressions</a></li><li><a href="ref_builtins_alphaidx.html">?builtins</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_specvar.html">.spec_vars</a></li><li><a href="app_faq.html">FAQ</a></li></ul></div></div></div> <div class="main-content site-width"> + <div class="content-wrapper"> + <div id="table-of-contents-wrapper" class="col-left"> + <script>var breadcrumb = ["Apache FreeMarker Manual","Template Author\'s Guide","The Template","Expressions"];</script> + <script src="toc.js?1489402528979"></script> + <script src="docgen-resources/main.min.js?1489402528979"></script> + </div> +<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_template_directives.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_template_valueinsertion.html"><span>Next</span></a></div><div class="title-wrapper"> +<h1 class="content-header header-section1" id="dgui_template_exp" itemprop="headline">Expressions</h1> +</div></div><div class="page-menu"> +<div class="page-menu-title">Page Contents</div> +<ul><li><a class="page-menu-link" href="#exp_cheatsheet" data-menu-target="exp_cheatsheet">Quick overview (cheat sheet)</a></li><li><a class="page-menu-link" href="#dgui_template_exp_direct" data-menu-target="dgui_template_exp_direct">Specify values directly</a><ul><li><a class="page-menu-link" href="#dgui_template_exp_direct_string" data-menu-target="dgui_template_exp_direct_string">Strings</a></li><li><a class="page-menu-link" href="#dgui_template_exp_direct_number" data-menu-target="dgui_template_exp_direct_number">Numbers</a></li><li><a class="page-menu-link" href="#dgui_template_exp_direct_boolean" data-menu-target="dgui_template_exp_direct_boolean">Booleans</a></li><li><a class="page-menu-link" href="#dgui_template_exp_direct_seuqence" data-menu-target="dgui_template_exp_direct_seuqence">Sequences</a></li><li><a class="page-menu-link" href="#dgui_template_exp_direct_ranges" data-menu-target="dgui_template_exp_direct_ranges">Ranges</a></li><li><a class="page-menu-link" href="#d gui_template_exp_direct_hash" data-menu-target="dgui_template_exp_direct_hash">Hashes</a></li></ul></li><li><a class="page-menu-link" href="#dgui_template_exp_var" data-menu-target="dgui_template_exp_var">Retrieving variables</a><ul><li><a class="page-menu-link" href="#dgui_template_exp_var_toplevel" data-menu-target="dgui_template_exp_var_toplevel">Top-level variables</a></li><li><a class="page-menu-link" href="#dgui_template_exp_var_hash" data-menu-target="dgui_template_exp_var_hash">Retrieving data from a hash</a></li><li><a class="page-menu-link" href="#dgui_template_exp_var_sequence" data-menu-target="dgui_template_exp_var_sequence">Retrieving data from a sequence</a></li><li><a class="page-menu-link" href="#dgui_template_exp_var_special" data-menu-target="dgui_template_exp_var_special">Special variables</a></li></ul></li><li><a class="page-menu-link" href="#dgui_template_exp_stringop" data-menu-target="dgui_template_exp_stringop">String operations</a><ul><li><a class="page-men u-link" href="#dgui_template_exp_stringop_interpolation" data-menu-target="dgui_template_exp_stringop_interpolation">Interpolation and concatenation</a></li><li><a class="page-menu-link" href="#dgui_template_exp_get_character" data-menu-target="dgui_template_exp_get_character">Getting a character</a></li><li><a class="page-menu-link" href="#dgui_template_exp_stringop_slice" data-menu-target="dgui_template_exp_stringop_slice">String slicing (substrings)</a></li></ul></li><li><a class="page-menu-link" href="#dgui_template_exp_sequenceop" data-menu-target="dgui_template_exp_sequenceop">Sequence operations</a><ul><li><a class="page-menu-link" href="#dgui_template_exp_sequenceop_cat" data-menu-target="dgui_template_exp_sequenceop_cat">Concatenation</a></li><li><a class="page-menu-link" href="#dgui_template_exp_seqenceop_slice" data-menu-target="dgui_template_exp_seqenceop_slice">Sequence slicing</a></li></ul></li><li><a class="page-menu-link" href="#dgui_template_exp_hashop" data-menu-ta rget="dgui_template_exp_hashop">Hash operations</a><ul><li><a class="page-menu-link" href="#dgui_template_exp_hashop_cat" data-menu-target="dgui_template_exp_hashop_cat">Concatenation</a></li></ul></li><li><a class="page-menu-link" href="#dgui_template_exp_arit" data-menu-target="dgui_template_exp_arit">Arithmetical calculations</a></li><li><a class="page-menu-link" href="#dgui_template_exp_comparison" data-menu-target="dgui_template_exp_comparison">Comparison</a></li><li><a class="page-menu-link" href="#dgui_template_exp_logicalop" data-menu-target="dgui_template_exp_logicalop">Logical operations</a></li><li><a class="page-menu-link" href="#dgui_template_exp_builtin" data-menu-target="dgui_template_exp_builtin">Built-ins</a></li><li><a class="page-menu-link" href="#dgui_template_exp_methodcall" data-menu-target="dgui_template_exp_methodcall">Method call</a></li><li><a class="page-menu-link" href="#dgui_template_exp_missing" data-menu-target="dgui_template_exp_missing">Handling miss ing values</a><ul><li><a class="page-menu-link" href="#dgui_template_exp_missing_default" data-menu-target="dgui_template_exp_missing_default">Default value operator</a></li><li><a class="page-menu-link" href="#dgui_template_exp_missing_test" data-menu-target="dgui_template_exp_missing_test">Missing value test operator</a></li></ul></li><li><a class="page-menu-link" href="#dgui_template_exp_assignment" data-menu-target="dgui_template_exp_assignment">Assignment Operators</a></li><li><a class="page-menu-link" href="#dgui_template_exp_parentheses" data-menu-target="dgui_template_exp_parentheses">Parentheses</a></li><li><a class="page-menu-link" href="#dgui_template_exp_whitespace" data-menu-target="dgui_template_exp_whitespace">White-space in expressions</a></li><li><a class="page-menu-link" href="#dgui_template_exp_precedence" data-menu-target="dgui_template_exp_precedence">Operator precedence</a></li></ul> </div><p>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 <code class="inline-code">(x + + y)/2</code> resolves to the numerical value 6.5.</p><p>Before we go into details, let's see some concrete + examples:</p><ul> + <li> + <p>When you supply value for interpolations: The usage of + interpolations is + <code class="inline-code">${<em class="code-color">expression</em>}</code> where + expression gives the value you want to insert into the output as + text. So <code class="inline-code">${(5 + 8)/2}</code> prints "6.5" + to the output (or possibly "6,5" if the language of + your output is not US English).</p> + </li> + + <li> + <p>When you supply a value for the directive parameter: You + have already seen the <code class="inline-code">if</code> directive in the + Getting Started section. The syntax of this directive is: + <code class="inline-code"><#if + <em class="code-color">expression</em>><em class="code-color">...</em></#if></code>. + The expression here must evaluate to a boolean value. For example + in <code class="inline-code"><#if 2 < 3></code> the <code class="inline-code">2 < + 3</code> (2 is less than 3) is an expression which evaluates to + <code class="inline-code">true</code>.</p> + </li> + </ul> + + + + +<h2 class="content-header header-section2" id="exp_cheatsheet">Quick overview (cheat sheet)</h2> + + + <p>This is a reminder for those of you who already know + FreeMarker or are just experienced programmers:</p> + + <ul> + <li> + <a href="#dgui_template_exp_direct">Specify values + directly</a> + + <ul> + <li> + <a href="#dgui_template_exp_direct_string">Strings</a>: + <code class="inline-code">"Foo"</code> or <code class="inline-code">'Foo'</code> or + <code class="inline-code">"It's \"quoted\""</code> or <code class="inline-code">'It\'s + "quoted"'</code> or + <code class="inline-code">r"C:\raw\string"</code> + </li> + + <li> + <a href="#dgui_template_exp_direct_number">Numbers</a>: + <code class="inline-code">123.45</code> + </li> + + <li> + <a href="#dgui_template_exp_direct_boolean">Booleans</a>: + <code class="inline-code">true</code>, <code class="inline-code">false</code> + </li> + + <li> + <a href="#dgui_template_exp_direct_seuqence">Sequences</a>: + <code class="inline-code">["foo", "bar", 123.45]</code>; Ranges: + <code class="inline-code">0..9</code>, <code class="inline-code">0..<10</code> (or + <code class="inline-code">0..!10</code>), <code class="inline-code">0..</code> + </li> + + <li> + <a href="#dgui_template_exp_direct_hash">Hashes</a>: + <code class="inline-code">{"name":"green mouse", + "price":150}</code> + </li> + </ul> + </li> + + <li> + <a href="#dgui_template_exp_var">Retrieving + variables</a> + + <ul> + <li> + <a href="#dgui_template_exp_var_toplevel">Top-level + variables</a>: <code class="inline-code">user</code> + </li> + + <li> + <a href="#dgui_template_exp_var_hash">Retrieving + data from a hash</a>: <code class="inline-code">user.name</code>, + <code class="inline-code">user["name"]</code> + </li> + + <li> + <a href="#dgui_template_exp_var_sequence">Retrieving data + from a sequence</a>: + <code class="inline-code">products[5]</code> + </li> + + <li> + <a href="#dgui_template_exp_var_special">Special + variable</a>: <code class="inline-code">.main</code> + </li> + </ul> + </li> + + <li> + <a href="#dgui_template_exp_stringop">String + operations</a> + + <ul> + <li> + <a href="#dgui_template_exp_stringop_interpolation">Interpolation + and concatenation</a>: + <code class="inline-code">"Hello ${user}!"</code> (or <code class="inline-code">"Hello + " + user + "!"</code>) + </li> + + <li> + <a href="#dgui_template_exp_get_character">Getting a + character</a>: <code class="inline-code">name[0]</code> + </li> + + <li> + <a href="#dgui_template_exp_stringop_slice">String + slice:</a> Inclusive end: <code class="inline-code">name[0..4]</code>, + Exclusive end: <code class="inline-code">name[0..<5]</code>, + Length-based (lenient): <code class="inline-code">name[0..*5]</code>, + Remove starting: <code class="inline-code">name[5..]</code> + </li> + </ul> + </li> + + <li> + <a href="#dgui_template_exp_sequenceop">Sequence + operations</a> + + <ul> + <li> + <a href="#dgui_template_exp_sequenceop_cat">Concatenation</a>: + <code class="inline-code">users + ["guest"]</code> + </li> + + <li> + <a href="#dgui_template_exp_seqenceop_slice">Sequence + slice</a>: Inclusive end: + <code class="inline-code">products[20..29]</code>, Exclusive end: + <code class="inline-code">products[20..<30]</code>, Length-based + (lenient): <code class="inline-code">products[20..*10]</code>, Remove + starting: <code class="inline-code">products[20..]</code> + </li> + </ul> + </li> + + <li> + <a href="#dgui_template_exp_hashop">Hash + operations</a> + + <ul> + <li> + <a href="#dgui_template_exp_hashop_cat">Concatenation</a>: + <code class="inline-code">passwords + { "joe": "secret42" }</code> + </li> + </ul> + </li> + + <li> + <a href="#dgui_template_exp_arit">Arithmetical + calculations</a>: <code class="inline-code">(x * 1.5 + 10) / 2 - y % + 100</code> + </li> + + <li> + <a href="#dgui_template_exp_comparison">Comparison</a>: + <code class="inline-code">x == y</code>, <code class="inline-code">x != y</code>, + <code class="inline-code">x < y</code>, <code class="inline-code">x > y</code>, + <code class="inline-code">x >= y</code>, <code class="inline-code">x <= y</code>, + <code class="inline-code">x lt y</code>, <code class="inline-code">x lte y</code>, + <code class="inline-code">x gt y</code>, <code class="inline-code">x gte y</code>, + ...etc. + </li> + + <li> + <a href="#dgui_template_exp_logicalop">Logical + operations</a>: <code class="inline-code">!registered && (firstVisit + || fromEurope)</code> + </li> + + <li> + <a href="#dgui_template_exp_builtin">Built-ins</a>: + <code class="inline-code">name?upper_case</code>, + <code class="inline-code">path?ensure_starts_with('/')</code> + </li> + + <li> + <a href="#dgui_template_exp_methodcall">Method + call</a>: <code class="inline-code">repeat("What", 3)</code> + </li> + + <li> + <a href="#dgui_template_exp_missing">Missing value + handler operators</a>: + + <ul> + <li> + <a href="#dgui_template_exp_missing_default">Default + value</a>: <code class="inline-code">name!"unknown"</code> or + <code class="inline-code">(user.name)!"unknown"</code> or + <code class="inline-code">name!</code> or + <code class="inline-code">(user.name)!</code> + </li> + + <li> + <a href="#dgui_template_exp_missing_test">Missing + value test</a>: <code class="inline-code">name??</code> or + <code class="inline-code">(user.name)??</code> + </li> + </ul> + </li> + + <li> + <a href="#dgui_template_exp_assignment">Assignment + operators</a>: <code class="inline-code">=</code>, <code class="inline-code">+=</code>, + <code class="inline-code">-=</code>, <code class="inline-code">*=</code>, + <code class="inline-code">/=</code>, <code class="inline-code">%=</code>, + <code class="inline-code">++</code>, <code class="inline-code">--</code> + </li> + </ul> + + <p>See also: <a href="#dgui_template_exp_precedence">Operator + precedence</a></p> + + + + + +<h2 class="content-header header-section2" id="dgui_template_exp_direct">Specify values directly</h2> + + + + + + + <p>Often you want to specify a value directly and not as a result + of some calculations.</p> + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_direct_string">Strings</h3> + + + + + <p>To specify a string value directly you give the text in + quotation marks, e.g.: <code class="inline-code">"some text"</code> or in + apostrophe-quote, e.g. <code class="inline-code">'some text'</code>. The two + forms are equivalent. If the text itself contains the character + used for the quoting (either <code class="inline-code">"</code> or + <code class="inline-code">'</code>) or backslashes, you have to precede them + with a backslash; this is called escaping. You can type any other + character, including <a href="gloss.html#gloss.lineBreak">line + breaks</a>, in the text directly. Example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${"It's \"quoted\" and +this is a backslash: \\"} + +${'It\'s "quoted" and +this is a backslash: \\'}</pre></div> + + <p>will print:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">It's "quoted" and +this is a backslash: \ + +It's "quoted" and +this is a backslash: \</pre></div> + + <div class="callout note"> + <strong class="callout-label">Note:</strong> + + <p>Of course, you could simply type the above text into the + template, without using + <code class="inline-code">${<em class="code-color">...</em>}</code>. But we do + it here just for the sake of example, to demonstrate + expressions.</p> + </div> + + + <a name="topic.escapeSequence"></a> + + + + <p>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.</p> + + <div class="table-responsive"> + <table class="table"> + + <thead> + <tr> + <th>Escape sequence</th> + + + <th>Meaning</th> + + </tr> + + </thead> + + + <tbody> + <tr> + <td><code class="inline-code">\"</code></td> + + + <td>Quotation mark (u0022)</td> + + </tr> + + + <tr> + <td><code class="inline-code">\'</code></td> + + + <td>Apostrophe (a.k.a. apostrophe-quote) (u0027)</td> + + </tr> + + + <tr> + <td><code class="inline-code">\{</code></td> + + + <td>Opening curly brace: <code class="inline-code">{</code></td> + + </tr> + + + <tr> + <td><code class="inline-code">\\</code></td> + + + <td>Back slash (u005C)</td> + + </tr> + + + <tr> + <td><code class="inline-code">\n</code></td> + + + <td>Line feed (u000A)</td> + + </tr> + + + <tr> + <td><code class="inline-code">\r</code></td> + + + <td>Carriage return (u000D)</td> + + </tr> + + + <tr> + <td><code class="inline-code">\t</code></td> + + + <td>Horizontal tabulation (a.k.a. tab) (u0009)</td> + + </tr> + + + <tr> + <td><code class="inline-code">\b</code></td> + + + <td>Backspace (u0008)</td> + + </tr> + + + <tr> + <td><code class="inline-code">\f</code></td> + + + <td>Form feed (u000C)</td> + + </tr> + + + <tr> + <td><code class="inline-code">\l</code></td> + + + <td>Less-than sign: <code class="inline-code"><</code></td> + + </tr> + + + <tr> + <td><code class="inline-code">\g</code></td> + + + <td>Greater-than sign: <code class="inline-code">></code></td> + + </tr> + + + <tr> + <td><code class="inline-code">\a</code></td> + + + <td>Ampersand: <code class="inline-code">&</code></td> + + </tr> + + + <tr> + <td><code class="inline-code">\x<em class="code-color">Code</em></code></td> + + + <td>Character given with its hexadecimal <a href="gloss.html#gloss.unicode">Unicode</a> code (<a href="gloss.html#gloss.UCS">UCS</a> code)</td> + + </tr> + + </tbody> + + </table> + </div> + + + <p>The <code class="inline-code"><em class="code-color">Code</em></code> after + the <code class="inline-code">\x</code> is 1 to 4 hexadecimal digits. For + example this all put a copyright sign into the string: + <code class="inline-code">"\xA9 1999-2001"</code>, + <code class="inline-code">"\x0A9 1999-2001"</code>, + <code class="inline-code">"\x00A9 1999-2001"</code>. When the character directly + after the last hexadecimal digit can be interpreted as hexadecimal + digit, you must use all 4 digits or else FreeMarker will + misunderstand you.</p> + + <p>Note that the character sequence <code class="inline-code">${</code> (and + <code class="inline-code">#{</code>) has special meaning. It's used to insert + the value of expressions (typically: the value of variables, as in + <code class="inline-code">"Hello ${user}!"</code>). This will be explained <a href="#dgui_template_exp_stringop_interpolation">later</a>. + If you want to print <code class="inline-code">${</code> or + <code class="inline-code">#{</code>, you should either use raw string literals + as explained below, or escape the <code class="inline-code">{</code> like in + <code class="inline-code">"foo $\{bar}"</code>.</p> + + + + <p>A special kind of string literals is the raw string + literals. In raw string literals, backslash and + <code class="inline-code">${</code> 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 <code class="inline-code">r</code> directly + before the opening quotation mark or apostrophe-quote. + Example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${r"${foo}"} +${r"C:\foo\bar"}</pre></div> + + <p>will print:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">${foo} +C:\foo\bar</pre></div> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_direct_number">Numbers</h3> + + + + + <p>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 <code class="inline-code">-</code> or <code class="inline-code">+</code> to indicate the + sign (<code class="inline-code">+</code> is redundant). Scientific notation is + not yet supported (so <code class="inline-code">1E3</code> is wrong). Also, you + cannot omit the 0 before the decimal separator (so + <code class="inline-code">.5</code> is wrong).</p> + + <p>Examples of valid number literals: <code class="inline-code">0.08</code>, + <code class="inline-code">-5.013</code>, <code class="inline-code">8</code>, + <code class="inline-code">008</code>, <code class="inline-code">11</code>, + <code class="inline-code">+11</code></p> + + <p>Note that numerical literals like <code class="inline-code">08</code>, + <code class="inline-code">+8</code>, <code class="inline-code">8.00</code> and + <code class="inline-code">8</code> are totally equivalent as they all symbolize + the number eight. Thus, <code class="inline-code">${08}</code>, + <code class="inline-code">${+8}</code>, <code class="inline-code">${8.00}</code> and + <code class="inline-code">${8}</code> will all print exactly same.</p> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_direct_boolean">Booleans</h3> + + + + + + + <p>To specify a boolean value you write <code class="inline-code">true</code> + or <code class="inline-code">false</code>. Don't use quotation marks.</p> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_direct_seuqence">Sequences</h3> + + + + + + + + + + + <p>To specify a literal sequence, you list the <a href="dgui_quickstart_datamodel.html#topic.dataModel.subVar">sub variables</a> separated by + commas, and put the whole list into square brackets. For + example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template"><#list <strong>["foo", "bar", "baz"]</strong> as x> +${x} +</#list></pre></div> + + <p>will print:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">foo +bar +baz + </pre></div> + + <p>The items in the list are expressions, so you can do this + for example: <code class="inline-code">[2 + 2, [1, 2, 3, 4], "foo"]</code>. Here + the first subvariable will be the number 4, the second will be + another sequence, and the third subvariable will be the string + "foo".</p> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_direct_ranges">Ranges</h3> + + + <p>Ranges are just sequences, but they are created by + specifying what range of whole numbers they contain, instead of + specifying their items one by one. For example, + <code class="inline-code">0..<m</code>, assuming the <code class="inline-code">m</code> + variable stores 5, will give a sequence that contains <code class="inline-code">[0, + 1, 2, 3, 4]</code>. Ranges are primarily used for iterating + over a range of numbers with <code class="inline-code"><#list + <em class="code-color">...</em>></code> and for <a href="#dgui_template_exp_seqenceop_slice">slicing + sequences</a> and <a href="#dgui_template_exp_stringop_slice">slicing + strings</a>.</p> + + <p>The generic forms of range expressions are (where + <code class="inline-code"><em class="code-color">start</em></code> and + <code class="inline-code"><em class="code-color">end</em></code> can be any + expression that evaluates to a number):</p> + + <ul> + <li> + <p><code class="inline-code"><em class="code-color">start</em>..<em class="code-color">end</em></code>: + Range with inclusive end. For example, <code class="inline-code">1..4</code> + gives <code class="inline-code">[1, 2, 3, 4]</code>, and + <code class="inline-code">4..1</code> gives <code class="inline-code">[4, 3, 2, 1]</code>. + Beware, ranges with inclusive end never give an empty + sequence, so <code class="inline-code">0..length-1</code> is + <em>WRONG</em>, because when length is + <code class="inline-code">0</code> it gives <code class="inline-code">[0, + -1]</code>.</p> + </li> + + <li> + <p><code class="inline-code"><em class="code-color">start</em>..<<em class="code-color">end</em></code> + or + <code class="inline-code"><em class="code-color">start</em>..!<em class="code-color">end</em></code>: + Range with exclusive end. For example, + <code class="inline-code">1..<4</code> gives <code class="inline-code">[1, 2, + 3]</code>, <code class="inline-code">4..<1</code> gives <code class="inline-code">[4, + 3, 2]</code>, and <code class="inline-code">1..<1</code> gives + <code class="inline-code">[]</code>. Note the last example; the result can + be an empty sequence. There's no difference between + <code class="inline-code">..<</code> and <code class="inline-code">..!</code>; the last + form is used in applications where using the + <code class="inline-code"><</code> character causes problems (for HTML + editors and such).</p> + </li> + + <li> + <p><code class="inline-code"><em class="code-color">start</em>..*<em class="code-color">length</em></code>: + Length limited range. For example, <code class="inline-code">10..*4</code> + gives <code class="inline-code">[10, 11, 12, 13]</code>, + <code class="inline-code">10..*-4</code> gives <code class="inline-code">[10, 9, 8, + 7]</code>, and <code class="inline-code">10..*0</code> gives + <code class="inline-code">[]</code>. When these kind of ranges are used for + slicing, the slice will end without error if the end of the + sliced sequence or string is reached before the specified + range length was reached; see <a href="#dgui_template_exp_seqenceop_slice">slicing + sequences</a> for more.</p> + + <div class="callout note"> + <strong class="callout-label">Note:</strong> + + <p>Length limited ranges were introduced in FreeMarker + 2.3.21.</p> + </div> + + </li> + + <li> + <p><code class="inline-code"><em class="code-color">start</em>..</code>: + Right-unbounded range. This are like length limited ranges + with infinite length. For example <code class="inline-code">1..</code> gives + <code class="inline-code">[1, 2, 3, 4, 5, 6, ... ]</code>, up to infinity. + Be careful when processing (like listing) such ranges, as + processing all items of it it would take forever or until the + application runs out of memory and crashes. Just like with + length limited ranges, when these kind of ranges are used for + slicing, the slice will end when the end of the sliced + sequence or string is reached.</p> + + <div class="callout warning"> + <strong class="callout-label">Warning!</strong> + + <p>Right-unbounded ranges before FreeMarker 2.3.21 were + only used for slicing, and behaved like an empty sequence + for other purposes. To activate the new behavior, it's not + enough to use FreeMarker 2.3.21, the programmer also have to + set the <code class="inline-code">incompatible_improvements</code> + configuration setting to at least 2.3.21.</p> + </div> + + </li> + </ul> + + <p>Further notes on ranges:</p> + + <ul> + <li> + <p>Range expressions themselves don't have square brackets, + for example, you write <code class="inline-code"><#assign myRange = + 0..<x</code>, NOT <code class="inline-code"><#assign myRange = + [0..<x]></code>. The last would create a sequence + that contains an item that's a range. The square brackets are + part of the slicing syntax, like + <code class="inline-code"><em class="code-color">seq</em>[<em class="code-color">myRange</em>]</code>.</p> + </li> + + <li> + <p>You can write arithmetical expression on the sides of + the <code class="inline-code">..</code> without parenthesis, like <code class="inline-code">n + + 1 ..< m / 2 - 1</code>.</p> + </li> + + <li> + <p><code class="inline-code">..</code>, <code class="inline-code">..<</code>, + <code class="inline-code">..!</code> and <code class="inline-code">..*</code> are + operators, so you can't have space inside them. Like + <code class="inline-code">n .. <m</code> is WRONG, but <code class="inline-code">n ..< + m</code> is good.</p> + </li> + + <li> + <p>The reported size of right-unbounded ranges is + 2147483647 (or 0 if + <code class="inline-code">incompatible_improvements</code> is less than + 2.3.21) due to a technical limitation (32 bits). However, when + listing them, their actual size is infinite.</p> + </li> + + <li> + <p>Ranges don't really store the numbers they consist of, + thus for example <code class="inline-code">0..1</code> and + <code class="inline-code">0..100000000</code> is equally fast to create and + takes the same amount of memory.</p> + </li> + </ul> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_direct_hash">Hashes</h3> + + + + + + + <p>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: <code class="inline-code">{ "name": "green mouse", + "price": 150 }</code>. Note that both the names and the values + are expressions. The keys must be strings. The values can be if + any type.</p> + + + + + + +<h2 class="content-header header-section2" id="dgui_template_exp_var">Retrieving variables</h2> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_var_toplevel">Top-level variables</h3> + + + + + <p>To access a top-level variable, you simply use the variable + name. For example, the expression <code class="inline-code">user</code> will + evaluate to the value of variable stored with name + "user" in the root. So this will print what you store + there:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${user}</pre></div> + + <p>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).</p> + + <p>In this kind of expression, the variable name can only + contain letters (including non-Latin letters), digits (including + non-Latin digits), underline (<code class="inline-code">_</code>), dollar + (<code class="inline-code">$</code>), at sign (<code class="inline-code">@</code>). + Furthermore, the first character can't be a ASCII digit + (<code class="inline-code">0</code>-<code class="inline-code">9</code>). Starting from + FreeMarker 2.3.22, the variable name can also contain minus + (<code class="inline-code">-</code>), dot (<code class="inline-code">.</code>), and colon + (<code class="inline-code">:</code>) at any position, but these must be escaped + with a preceding backslash (<code class="inline-code">\</code>), or else they + would be interpreted as operators. For example, to read the + variable whose name is "data-id", the expression is + <code class="inline-code">data\-id</code>, as <code class="inline-code">data-id</code> would + be interpreted as "data minus id". (Note that these + escapes only work in identifiers, not in string literals.)</p> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_var_hash">Retrieving data from a hash</h3> + + + + + + + <p>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:</p> + + + +<div class="code-wrapper"><pre class="code-block code-data-model">(root) + | + +- book + | | + | +- title = "Breeding green mouses" + | | + | +- author + | | + | +- name = "Julia Smith" + | | + | +- info = "Biologist, 1923-1985, Canada" + | + +- test = "title"</pre></div> + + <p>Now we can read the <code class="inline-code">title</code> with + <code class="inline-code">book.title</code>, 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: <code class="inline-code">book.author.name</code>.</p> + + <p>There is an alternative syntax if we want to specify the + subvariable name with an expression: + <code class="inline-code">book["title"]</code>. 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 + <code class="inline-code">book[test]</code>. More examples; these are all + equivalent: <code class="inline-code">book.author.name</code>, + <code class="inline-code">book["author"].name</code>, + <code class="inline-code">book.author.["name"]</code>, + <code class="inline-code">book["author"]["name"]</code>.</p> + + <p>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, <code class="inline-code">_</code>, + <code class="inline-code">$</code>, <code class="inline-code">@</code> but can't start with + <code class="inline-code">0</code>-<code class="inline-code">9</code>, also starting from + 2.3.22 you can also use <code class="inline-code">\-</code>, + <code class="inline-code">\.</code> and <code class="inline-code">\:</code>). 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 + <code class="inline-code">*</code> (asterisk) or <code class="inline-code">**</code>, then you + do not have to use square bracket syntax.)</p> + + <p>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).</p> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_var_sequence">Retrieving data from a sequence</h3> + + + + + + + <p>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 <a href="dgui_datamodel_basics.html#example.stdDataModel">example data-model</a> (remember + that the number of the first item is 0, not 1): + <code class="inline-code">animals[0].name</code></p> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_var_special">Special variables</h3> + + + + + <p>Special variables are variables defined by the FreeMarker + engine itself. To access them, you use the + <code class="inline-code">.<em class="code-color">variable_name</em></code> + syntax.</p> + + <p>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 <a href="ref_specvar.html">reference</a>.</p> + + + + + + +<h2 class="content-header header-section2" id="dgui_template_exp_stringop">String operations</h2> + + + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_stringop_interpolation">Interpolation and concatenation</h3> + + + + + + + + + + + + + + + <p>If you want to insert the value of an expression into a + string, you can use + <code class="inline-code">${<em class="code-color">...</em>}</code> (and the + deprecated <code class="inline-code">#{<em class="code-color">...</em>}</code>) + in string literals. + <code class="inline-code">${<em class="code-color">...</em>}</code> in string + literals <a href="dgui_template_valueinsertion.html">behaves + similarly as in <span class="marked-text">text</span> + sections</a> (so it goes through the same <em>locale + sensitive</em> number and date/time formatting).</p> + + <p>Example (assume that user is "Big Joe"):</p> + + + +<div class="code-wrapper"><pre class="code-block code-template"><#assign s = "Hello ${user}!"> +${s} <#-- Just to see what the value of s is --></pre></div> + + <p>This will print:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">Hello Big Joe!</pre></div> + + <div class="callout warning"> + <strong class="callout-label">Warning!</strong> + + <p>A frequent mistake of users is the usage of interpolations + in places where they needn't/shouldn't/can't be used. + Interpolations work <em>only</em> in <a href="dgui_template_overallstructure.html"><span class="marked-text">text</span> sections</a> (e.g. + <code class="inline-code"><h1>Hello ${name}!</h1></code>) and in + string literals (e.g. <code class="inline-code"><#include + "/footer/${company}.html"></code>). A typical + <em>WRONG</em> usage is <code class="inline-code"><#if + ${big}>...</#if></code>, which will cause a + syntactical error. You should simply write <code class="inline-code"><#if + big>...</#if></code>. Also, <code class="inline-code"><#if + "${big}">...</#if></code> is + <em>WRONG</em>, since it converts the parameter + value to string and the <code class="inline-code">if</code> directive wants a + boolean value, so it will cause a runtime error.</p> + </div> + + + <p><a name="dgui_template_exp_stringop_concatenation"></a>Alternatively, + you can use the <code class="inline-code">+</code> operator to achieve similar + result:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template"><#assign s = "Hello " + user + "!"></pre></div> + + <p>This gives the same result as the earlier example with the + <code class="inline-code">${<em class="code-color">...</em>}</code>.</p> + + <div class="callout warning"> + <strong class="callout-label">Warning!</strong> + + <p>Because <code class="inline-code">+</code> follows similar rules as + <code class="inline-code">${<em class="code-color">...</em>}</code>, the + appended string is influenced by the <code class="inline-code">locale</code>, + <code class="inline-code">number_format</code>, + <code class="inline-code">date_format</code>, <code class="inline-code">time_format</code>, + <code class="inline-code">datetime_format</code> and + <code class="inline-code">boolean_format</code>, etc. settings, and thus the + result targets humans and isn't in generally machine parseable. + This mostly leads to problems with numbers, as many locales use + grouping (thousands separators) by default, and so + <code class="inline-code">"someUrl?id=" + id</code> becomes to something like + <code class="inline-code">"someUrl?id=1 234"</code>. To prevent this, use the + <code class="inline-code">?c</code> (for Computer audience) built-in, like in + <code class="inline-code">"someUrl?id=" + id?c</code> or + <code class="inline-code">"someUrl?id=${id?c}"</code>, which will evaluate to + something like <code class="inline-code">"someUrl?id=1234"</code>, regardless + of locale and format settings.</p> + </div> + + + <p>As when <code class="inline-code">${<em class="code-color">...</em>}</code> + is used inside string <em>expressions</em> it's just a + shorthand of using the <code class="inline-code">+</code> operator, <a href="dgui_misc_autoescaping.html">auto-escaping</a> is not + applied on it.</p> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_get_character">Getting a character</h3> + + + + + + + <p>You can get a single character of a string at a given index + similarly as you can <a href="#dgui_template_exp_var_sequence">read the subvariable of a + sequence</a>, e.g. <code class="inline-code">user[0]</code>. The result will + be a string whose length is 1; FTL doesn't have a separate + character type. As with sequence sub variables, 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.</p> + + <p>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 + <a href="ref_builtins_string.html#ref_builtin_string_for_string">the + <code>string</code> built-in</a>, e.g. + <code class="inline-code">user?string[0]</code>. Don't worry if you don't + understand this yet; built-ins will be discussed later.)</p> + + <p>Example (assume that user is "Big Joe"):</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${user[0]} +${user[4]}</pre></div> + + <p>will print (note that the index of the first character is + 0):</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">B +J</pre></div> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_stringop_slice">String slicing (substrings)</h3> + + + + + + + + + + + <p>You can a slice a string in the same way as you <a href="#dgui_template_exp_seqenceop_slice">slice a + sequence</a> (see there), only here instead of sequence items + you work with characters. Some differences are:</p> + + <ul> + <li> + <p>Decreasing ranges aren't allowed for string slicing. + (That's because unlike sequences, you seldom if ever want to + show a string reversed, so if that happens, that's almost + always the result of an oversight.)</p> + </li> + + <li> + <p>If a value is both a string and a sequence (a + multi-typed value), then slicing will slice the sequence + instead of the string. When you are processing XML, such + values are common. In such cases you can use + <code class="inline-code"><em class="code-color">someXMLnode</em>?string[<em class="code-color">range</em>]</code>.</p> + </li> + + <li> + <p>There's a legacy bug where a range with + <em>inclusive</em> end that's one less than the + starting index and is non-negative (like in + <code class="inline-code">"abc"[1..0]</code>) will give an empty string + instead of an error. (It should be an error as it's a + decreasing range.) Currently this bug is emulated for backward + compatibility, but you shouldn't utilize it, as in the future + it will be certainly an error.</p> + </li> + </ul> + + <p>Example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template"><#assign s = "ABCDEF"> +${s[2..3]} +${s[2..<4]} +${s[2..*3]} +${s[2..*100]} +${s[2..]}</pre></div> + + <p>will print:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">CD +CD +CDE +CDEF +CDEF</pre></div> + + <div class="callout note"> + <strong class="callout-label">Note:</strong> + + <p>Some of the typical use-cases of string slicing is covered + by convenient built-ins: <a href="ref_builtins_string.html#ref_builtin_remove_beginning"><code>remove_beginning</code></a>, + <a href="ref_builtins_string.html#ref_builtin_remove_ending"><code>remove_ending</code></a>, + <a href="ref_builtins_string.html#ref_builtin_keep_before"><code>keep_before</code></a>, + <a href="ref_builtins_string.html#ref_builtin_keep_after"><code>keep_after</code></a>, + <a href="ref_builtins_string.html#ref_builtin_keep_before_last"><code>keep_before_last</code></a>, + <a href="ref_builtins_string.html#ref_builtin_keep_after_last"><code>keep_after_last</code></a></p> + </div> + + + + + + + +<h2 class="content-header header-section2" id="dgui_template_exp_sequenceop">Sequence operations</h2> + + + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_sequenceop_cat">Concatenation</h3> + + + + + + + + + + + <p>You can concatenate sequences in the same way as strings, + with <code class="inline-code">+</code>. Example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template"><#list ["Joe", "Fred"] + ["Julia", "Kate"] as user> +- ${user} +</#list></pre></div> + + <p>will print:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">- Joe +- Fred +- Julia +- Kate + </pre></div> + + <p>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 <code class="inline-code"><#list users + + admins as person></code>. 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.</p> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_seqenceop_slice">Sequence slicing</h3> + + + + + + + + + <p>With + <code class="inline-code"><em class="code-color">seq</em>[<em class="code-color">range</em>]</code>, + were <code class="inline-code"><em class="code-color">range</em></code> is a + range value <a href="#dgui_template_exp_direct_ranges">as + described here</a>, you can take a slice of the sequence. The + resulting sequence will contain the items from the original + sequence (<code class="inline-code"><em class="code-color">seq</em></code>) whose + indexes are in the range. For example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template"><#assert seq = ["A", "B", "C", "D", "E"]> +<#list seq[1..3] as i>${i}</#list></pre></div> + + <p>will print</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">BCD </pre></div> + + <p>Furthermore, the items in the slice will be in the same + order as in the range. Thus for example the above example with the + <code class="inline-code">3..1</code> range would print + <code class="inline-code">DCB</code>.</p> + + <p>The numbers in the range must be valid indexes in the + sequence, or else the processing of the template will be aborted + with error. Like in the last example, + <code class="inline-code">seq[-1..0]</code> would be an error as + <code class="inline-code">seq[-1]</code> is invalid, also + <code class="inline-code">seq[1..5]</code> would be because + <code class="inline-code">seq[5]</code> is invalid. (Note that + <code class="inline-code">seq[100..<100]</code> or + <code class="inline-code">seq[100..*0]</code> would be valid despite that 100 is + out of bounds, because those ranges are empty.)</p> + + <p>Length limited ranges + (<code class="inline-code"><em class="code-color">start</em>..*<em class="code-color">length</em></code>) + and right-unbounded ranges + (<code class="inline-code"><em class="code-color">start</em>..</code>) adapt to + the length of the sliced sequence. They will slice out at most as + many items as there is available:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template"><#assign seq = ["A", "B", "C"]> + +Slicing with length limited ranges: +- <#list seq[0..*2] as i>${i}</#list> +- <#list seq[1..*2] as i>${i}</#list> +- <#list seq[2..*2] as i>${i}</#list> <#-- Not an error --> +- <#list seq[3..*2] as i>${i}</#list> <#-- Not an error --> + +Slicing with right-unlimited ranges: +- <#list seq[0..] as i>${i}</#list> +- <#list seq[1..] as i>${i}</#list> +- <#list seq[2..] as i>${i}</#list> +- <#list seq[3..] as i>${i}</#list></pre></div> + + <p>This will print:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">Slicing with length limited ranges: +- AB +- BC +- C +- + +Slicing with right-unlimited ranges: +- ABC +- BC +- C +-</pre></div> + + <p>Note above that slicing with length limited and right + unbounded ranges allow the starting index to be past the last item + <em>by one</em> (but no more).</p> + + <div class="callout note"> + <strong class="callout-label">Note:</strong> + + <p>To split a sequence to slices of a given size, you should + use the <a href="ref_builtins_sequence.html#ref_builtin_chunk"><code>chunk</code></a> + built-in.</p> + </div> + + + + + + + +<h2 class="content-header header-section2" id="dgui_template_exp_hashop">Hash operations</h2> + + + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_hashop_cat">Concatenation</h3> + + + + + + + + + + + <p>You can concatenate hashes in the same way as strings, with + <code class="inline-code">+</code>. If both hashes contain the same key, the + hash on the right-hand side of the <code class="inline-code">+</code> takes + precedence. Example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template"><#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}> +- Joe is ${ages.Joe} +- Fred is ${ages.Fred} +- Julia is ${ages.Julia}</pre></div> + + <p>will print:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">- Joe is 30 +- Fred is 25 +- Julia is 18</pre></div> + + <p>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 <a href="#dgui_template_exp_sequenceop_cat">sequence + concatenation</a>.</p> + + + + + + +<h2 class="content-header header-section2" id="dgui_template_exp_arit">Arithmetical calculations</h2> + + + + + + + + + + + + + + + <p>This is the basic 4-function calculator arithmetic plus the + modulus operator. So the operators are:</p> + + <ul> + <li> + Addition: <code class="inline-code">+</code> + </li> + + <li> + Subtraction: <code class="inline-code">-</code> + </li> + + <li> + Multiplication: <code class="inline-code">*</code> + </li> + + <li> + Division: <code class="inline-code">/</code> + </li> + + <li> + Modulus (remainder) of integer operands: + <code class="inline-code">%</code> + </li> + </ul> + + + + <p>Example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${100 - x * x} +${x / 2} +${12 % 10}</pre></div> + + <p>Assuming that <code class="inline-code">x</code> is 5, it will print:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">75 +2.5 +2</pre></div> + + <p>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 <code class="inline-code">"5"</code> is a + string and not the number 5:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${3 * "5"} <#-- WRONG! --></pre></div> + + <p>There is an exception to the above rule. The + <code class="inline-code">+</code> operator, is used to <a href="#dgui_template_exp_stringop_interpolation">concatenate + strings</a> as well. If on one side of <code class="inline-code">+</code> is a + string and on the other side of <code class="inline-code">+</code> 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 + <code class="inline-code">+</code> as string concatenation operator. + Example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${3 + "5"}</pre></div> + + + +<div class="code-wrapper"><pre class="code-block code-output">35</pre></div> + + <p>Generally, FreeMarker never converts a string to a number + automatically, but it may convert a number to a string + automatically.</p> + + <p> People often want only the integer part of the result + of a division (or of other calculations). This is possible with the + <code class="inline-code">int</code> built-in. (Built-ins are explained <a href="#dgui_template_exp_builtin">later</a>):</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${(x/2)?int} +${1.1?int} +${1.999?int} +${-1.1?int} +${-1.999?int}</pre></div> + + <p>Assuming that <code class="inline-code">x</code> is 5, it will print:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">2 +1 +1 +-1 +-1</pre></div> + + <p>Due to historical reasons, the <code class="inline-code">%</code> operator + works by first truncating the operands to an integer number, and + then returning the remainder of the division:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${12 % 5} <#-- Prints 2 --> +${12.9 % 5} <#-- Prints 2 --> +${12.1 % 5} <#-- Prints 2 --> + +${12 % 6} <#-- Prints 0 --> +${12 % 6.9} <#-- Prints 0 --></pre></div> + + <p>The sign of the result of <code class="inline-code">%</code> is the same as + the sign of the left hand operand, and its absolute value is the + same as if both operands where positive:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${-12 % -5} <#-- Prints -2 --> +${-12 % 5} <#-- Prints -2 --> +${12 % -5} <#-- Prints 2 --></pre></div> + + + + + +<h2 class="content-header header-section2" id="dgui_template_exp_comparison">Comparison</h2> + + + + + <p>Sometimes you want to know if two values are equal or not, or + which value is the greater.</p> + + <p>To show concrete examples I will use the <code class="inline-code">if</code> + directive here. The usage of <code class="inline-code">if</code> directive is: + <code class="inline-code"><#if + <em class="code-color">expression</em>>...</#if></code>, + 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 <code class="inline-code">true</code> then the things between the + begin and end-tag will be processed, otherwise they will be + skipped.</p> + + <p>To test two values for equality you use <code class="inline-code">==</code> + (or <code class="inline-code">=</code> as a <em>deprecated</em> + alternative) To test two values for inequality you use + <code class="inline-code">!=</code>. For example, assume that + <code class="inline-code">user</code> is "Big Joe":</p> + + + +<div class="code-wrapper"><pre class="code-block code-template"><#if <strong>user == "Big Joe"</strong>> + It is Big Joe +</#if> +<#if <strong>user != "Big Joe"</strong>> + It is not Big Joe +</#if></pre></div> + + <p>The <code class="inline-code">user == "Big Joe"</code> expression in the + <code class="inline-code"><#if ...></code> will evaluate to the boolean + <code class="inline-code">true</code>, so the above will say "It is Big + Joe".</p> + + <p>The expressions on both sides of the <code class="inline-code">==</code> or + <code class="inline-code">!=</code> must evaluate to a scalar (not a sequence or + hash). 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 <code class="inline-code"><#if 1 == "1"></code> will + cause an error. Note that FreeMarker does exact comparison, so + string comparisons are case and white-space sensitive: + <code class="inline-code">"x"</code> and <code class="inline-code">"x "</code> and + <code class="inline-code">"X"</code> are not equal values.</p> + + <p>For numerical and date, time and date-time values you can also + use <code class="inline-code"><</code>, <code class="inline-code"><=</code>, + <code class="inline-code">>=</code> and <code class="inline-code">></code>. You can't use + them for strings! Example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template"><#if x <strong><=</strong> 12> + x is less or equivalent with 12 +</#if></pre></div> + + <p>There's a problem with <code class="inline-code">>=</code> and + <code class="inline-code">></code>. FreeMarker interprets the + <code class="inline-code">></code> character as the closing character of the + FTL tag. To prevent this, you can use <code class="inline-code">lt</code> instead + of <code class="inline-code"><</code>, <code class="inline-code">lte</code> instead of + <code class="inline-code"><=</code>, <code class="inline-code">gt</code> instead of + <code class="inline-code">></code> and <code class="inline-code">gte</code> instead of + <code class="inline-code">>=</code>, like in <code class="inline-code"><#if x gt + y></code>. Another trick it to put the expression into <a href="#dgui_template_exp_parentheses">parentheses</a> like in + <code class="inline-code"><#if (x > y)></code>, although it's considered + to be less elegant.</p> + + <div class="callout note"> + <strong class="callout-label">Note:</strong> + + <p>FreeMarker supports some other alternatives too, but these + are deprecated:</p> + + <ul> + <li> + <p>Writing <code class="inline-code">&gt;</code> and + <code class="inline-code">&lt;</code> on the place of the problematic + relation marks, like in: <code class="inline-code"><#if x &gt; + y></code> or <code class="inline-code"><#if x &gt;= + y></code> . Note that in general FTL does not support + entity references (the + <code class="inline-code">&<em class="code-color">...</em>;</code> + things) in FTL tags; it's just an exception with the + arithmetical comparisons.</p> + </li> + + <li> + <p><code class="inline-code">\lt</code>, <code class="inline-code">\lte</code>, + <code class="inline-code">\gt</code> and <code class="inline-code">\gte</code> which are + the same as the ones without the backslash</p> + </li> + </ul> + </div> + + + + + + +<h2 class="content-header header-section2" id="dgui_template_exp_logicalop">Logical operations</h2> + + + + + + + + + + + + + <p>Just the usual logical operators:</p> + + <ul> + <li> + Logical or: <code class="inline-code">||</code> + </li> + + <li> + Logical and: <code class="inline-code">&&</code> + </li> + + <li> + Logical not: <code class="inline-code">!</code> + </li> + </ul> + + <p>The operators will work with boolean values only. Otherwise an + error will abort the template processing.</p> + + <p>Example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template"><#if x < 12 <strong>&&</strong> color == "green"> + We have less than 12 things, and they are green. +</#if> +<#if <strong>!</strong>hot> <#-- here hot must be a boolean --> + It's not hot. +</#if></pre></div> + + + + + +<h2 class="content-header header-section2" id="dgui_template_exp_builtin">Built-ins</h2> + + + + + <p>Built-ins are like methods that are added to the objects by + FreeMarker. To prevent name clashes with actual methods and other + sub-variables, instead of dot (<code class="inline-code">.</code>), you separate + them from the parent object with question mark + (<code class="inline-code">?</code>). For example, if you want to ensure that + <code class="inline-code">path</code> has an initial <code class="inline-code">/</code> then you + could write <code class="inline-code">path?ensure_starts_with('/')</code>. The + Java object behind <code class="inline-code">path</code> (a + <code class="inline-code">String</code> most certainly) doesn't have such method, + FreeMarker adds it. For brevity, if the method has no parameters, + you <em>must</em> omit the <code class="inline-code">()</code>, like, + to get the length of <code class="inline-code">path</code>, you have to write + <code class="inline-code">path?length</code>, <em>not</em> + <code class="inline-code">path?length()</code>.</p> + + <p>The other reason why built-ins are crucial is that normally + (though it depends on configuration settings), FreeMarker doesn't + expose the Java API of the objects. So despite that Java's + <code class="inline-code">String</code> has a <code class="inline-code">length()</code> method, + it's hidden from the template, you <em>have to</em> use + <code class="inline-code">path?length</code> instead. The advantage of that is + that thus the template doesn't depend on the exactly type of the + underlying Java objects. (Like <code class="inline-code">path</code> is maybe a + <code class="inline-code">java.nio.Path</code> behind the scenes, but if the + programmers has configure FreeMarker to expose + <code class="inline-code">Path</code> objects as FTL strings, the template won't + be aware of that, and <code class="inline-code">?length</code> will work, despite + that <code class="inline-code">java.nio.Path</code> has no similar method.)</p> + + <p>You can find some of the <a href="dgui_quickstart_template.html#topic.commonlyUsedBuiltIns">most commonly used built-ins + mentioned here</a>, and the <a href="ref_builtins.html">complete + list of built-ins in the Reference</a>. For now, just a few of + the more important ones:</p> + + <p>Example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${testString?upper_case} +${testString?html} +${testString?upper_case?html} + +${testSequence?size} +${testSequence?join(", ")}</pre></div> + + <p>Assuming that <code class="inline-code">testString</code> stores the string + "Tom & Jerry", and testSequnce stores the strings + "foo", "bar" and "baz", the + output will be:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">TOM & JERRY +Tom &amp; Jerry +TOM &amp; JERRY + +3 +foo, bar, baz</pre></div> + + <p>Note the <code class="inline-code">test?upper_case?html</code> above. Since + the result of <code class="inline-code">test?upper_case</code> is a string, you + can apply the <code class="inline-code">html</code> built-in on it.</p> + + <p>Naturally, the left side of the built-in can be arbitrary + expression, not just a variable name:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${testSeqence[1]?cap_first} +${"horse"?cap_first} +${(testString + " & Duck")?html}</pre></div> + + + +<div class="code-wrapper"><pre class="code-block code-output">Bar +Horse +Tom &amp; Jerry &amp; Duck</pre></div> + + + + + +<h2 class="content-header header-section2" id="dgui_template_exp_methodcall">Method call</h2> + + + + + + + <p>If you have a method then you can use the method call + operation on it. The method call operation is a comma-separated list + of expressions in parentheses. These values are called parameters. + The method call operation passes these values to the method which + will in turn return a result. This result will be the value of the + whole method call expression.</p> + + <p>For example, assume the programmers have made available a + method variable called <code class="inline-code">repeat</code>. You give a string + as the first parameter, and a number as the second parameter, and it + returns a string which repeats the first parameter the number of + times specified by the second parameter.</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${repeat("Foo", 3)}</pre></div> + + <p>will print:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">FooFooFoo</pre></div> + + <p>Here <code class="inline-code">repeat</code> was evaluated to the method + variable (according to how you <a href="#dgui_template_exp_var_toplevel">access top-level + variables</a>) and then <code class="inline-code">("What", 3)</code> invoked + that method.</p> + + <p>I would like to emphasize that method calls are just plain + expressions, like everything else. So this:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${repeat(repeat("x", 2), 3) + repeat("Foo", 4)?upper_case}</pre></div> + + <p>will print this:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">xxxxxxFOOFOOFOOFOO</pre></div> + + + + + +<h2 class="content-header header-section2" id="dgui_template_exp_missing">Handling missing values</h2> + + + <div class="callout note"> + <strong class="callout-label">Note:</strong> + + <p>These operators exist since FreeMarker 2.3.7 (replacing the + <code class="inline-code">default</code>, <code class="inline-code">exists</code> and + <code class="inline-code">if_exists</code> built-ins).</p> + </div> + + + + + + + + + + + + + <p>As we explained earlier, an error will occur and abort the + template processing if you try to access a missing variable. However + two special operators can suppress this error, and handle the + problematic situation. The handled variable can be top-level + variable, hash subvariable, or sequence subvariable as well. + Furthermore these operators handle the situation when a method call + doesn't return a value <span class="marked-for-programmers">(from the + viewpoint of Java programmers: it returns <code class="inline-code">null</code> or + it's return type is <code class="inline-code">void</code>)</span>, so it's more + correct to say that these operators handle missing values in + general, rather than just missing variables.</p> + + <p><span class="marked-for-programmers">For those who know what's Java + <code class="inline-code">null</code>, FreeMarker 2.3.<em>x</em> + treats them as missing values. Simply, the template language doesn't + know the concept of <code class="inline-code">null</code>. For example, if you + have a bean that has a <code class="inline-code">maidenName</code> property, and + the value of that property is <code class="inline-code">null</code>, then that's + the same as if there were no such property at all, as far as the + template is concerned (assuming you didn't configured FreeMarker to + use some extreme object wrapper, that is). The result of a method + call that returns <code class="inline-code">null</code> is also treated as a + missing variable (again, assuming that you use some usual object + wrapper). See more <a href="app_faq.html#faq_null">in the + FAQ</a>.</span></p> + + <div class="callout note"> + <strong class="callout-label">Note:</strong> + + <p>If you wonder why is FreeMarker so picky about missing + variables, <a href="app_faq.html#faq_picky_about_missing_vars">read this + FAQ entry</a>.</p> + </div> + + + + + + + +<h3 class="content-header header-section3" id="dgui_template_exp_missing_default">Default value operator</h3> + + + + + <p>Synopsis: + <code class="inline-code"><em class="code-color">unsafe_expr</em>!<em class="code-color">default_expr</em></code> + or <code class="inline-code"><em class="code-color">unsafe_expr</em>!</code> or + <code class="inline-code">(<em class="code-color">unsafe_expr</em>)!<em class="code-color">default_expr</em></code> + or + <code class="inline-code">(<em class="code-color">unsafe_expr</em>)!</code></p> + + <p>This operator allows you to specify a default value for the + case when the value is missing.</p> + + <p>Example. Assume no variable called <code class="inline-code">mouse</code> + is present:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">${mouse!"No mouse."} +<#assign mouse="Jerry"> +${mouse!"No mouse."}</pre></div> + + <p>The output will be:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">No mouse. +Jerry</pre></div> + + <p>The default value can be any kind of expression, so it + doesn't have to be a string. For example you can write + <code class="inline-code">hits!0</code> or <code class="inline-code">colors!["red", "green", + "blue"]</code>. There is no restriction regarding the + complexity of the expression that specifies the default value, for + example you can write: <code class="inline-code">cargo.weight!(item.weight * + itemCount + 10)</code>.</p> + + <div class="callout warning"> + <strong class="callout-label">Warning!</strong> + + <p>If you have a composite expression after the + <code class="inline-code">!</code>, like <code class="inline-code">1 + x</code>, + <em>always</em> use parenthesses, like + <code class="inline-code">${x!(1 + y)}</code> or <code class="inline-code">${(x!1) + + y)}</code>, depending on which interpretation you meant. + That's needed because due to a programming mistake in FreeMarker + 2.3.x, the precedence of <code class="inline-code">!</code> (when it's used as + default value operator) is very low at its right side. This + means that, for example, <code class="inline-code">${x!1 + y}</code> is + misinterpreted by FreeMarker as <code class="inline-code">${x!(1 + y)}</code> + while it should mean <code class="inline-code">${(x!1) + y}</code>. This + programming error will be fixed in FreeMarker 2.4, so you should + not utilize this wrong behavior, or else your templates will + break with FreeMarker 2.4!</p> + </div> + + + <p>If the default value is omitted, then it will be empty + string and empty sequence and empty hash at the same time. (This + is possible because FreeMarker allows multi-type values.) Note the + consequence that you can't omit the default value if you want it + to be <code class="inline-code">0</code> or <code class="inline-code">false</code>. + Example:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">(${mouse!}) +<#assign mouse = "Jerry"> +(${mouse!})</pre></div> + + <p>The output will be:</p> + + + +<div class="code-wrapper"><pre class="code-block code-output">() +(Jerry)</pre></div> + + <div class="callout warning"> + <strong class="callout-label">Warning!</strong> + + <p>Due to syntactical ambiguities <code class="inline-code"><@something + a=x! b=y /></code> will be interpreted as + <code class="inline-code"><@something a=x!(b=y) /></code>, that is, the + <code class="inline-code">b=y</code> will be interpreted as a comparison that + gives the default value for <code class="inline-code">x</code>, rather than + the specification of the <code class="inline-code">b</code> parameter. To + prevent this, write: <code class="inline-code"><@something a=(x!) b=y + /></code></p> + </div> + + + <p>You can use this operator in two ways with non-top-level + variables:</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">product.color!"red"</pre></div> + + <p>This will handle if <code class="inline-code">color</code> is missing + inside <code class="inline-code">product</code> (and returns + <code class="inline-code">"red"</code> if so), but will not handle if + <code class="inline-code">product</code> is missing. That is, the + <code class="inline-code">product</code> variable itself must exist, otherwise + the template processing will die with error.</p> + + + +<div class="code-wrapper"><pre class="code-block code-template">(product.color)!"
<TRUNCATED>
