blob: cbd2f9fd4cd2995e551d9e7c24fdeee0e7820ffc [file] [log] [blame]
<!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>2.3.23 - 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="2.3.23">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="https://freemarker.apache.org/docs/versions_2_3_23.html">
<link rel="canonical" href="https://freemarker.apache.org/docs/versions_2_3_23.html">
<link rel="icon" href="favicon.png" type="image/png">
<link rel="stylesheet" type="text/css" href="https://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?1707770044859">
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/cookie-bar/cookiebar-latest.min.js"></script>
</head>
<body itemscope itemtype="https://schema.org/Code">
<meta itemprop="url" content="https://freemarker.apache.org/docs/">
<meta itemprop="name" content="Apache FreeMarker Manual">
<!--[if lte IE 9]>
<div class="oldBrowserWarning" style="display: block">
Unsupported web browser - Use a modern browser to view this website!
</div>
<![endif]--> <div class="oldBrowserWarning">
Unsupported web browser - Use a modern browser to view this website!
</div>
<div class="header-top-bg"><div class="site-width header-top"><div id="hamburger-menu" role="button"></div> <div class="logo">
<a href="https://freemarker.apache.org" role="banner"><img itemprop="image" src="logo.png" alt="FreeMarker"></a> </div>
<ul class="tabs"><li><a href="https://freemarker.apache.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="https://freemarker.apache.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/projects/FREEMARKER" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="https://freemarker.apache.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="search-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"> <div class="breadcrumbs">
<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="app.html"><span itemprop="name">Appendixes</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="app_versions.html"><span itemprop="name">Version history</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="versions_2_3_23.html"><span itemprop="name">2.3.23</span></a></li></ul> </div>
<div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul><li><a href="alphaidx.html">Alpha. index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="dgui_template_exp.html#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","Appendixes","Version history","2.3.23"];</script>
<script src="toc.js?1707770044859"></script>
<script src="docgen-resources/main.min.js?1707770044859"></script>
</div>
<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="versions_2_3_24.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3_22.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="versions_2_3_23" itemprop="headline">2.3.23</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#autoid_172" data-menu-target="autoid_172">Changes on the FTL side</a></li><li><a class="page-menu-link" href="#autoid_173" data-menu-target="autoid_173">Changes on the Java side</a></li><li><a class="page-menu-link" href="#autoid_174" data-menu-target="autoid_174">Other changes</a></li><li><a class="page-menu-link" href="#autoid_175" data-menu-target="autoid_175">Notes</a></li></ul> </div><p>Date of release: 2015-07-05</p>
<h2 class="content-header header-section2" id="autoid_172">Changes on the FTL side</h2>
<ul>
<li>
<p>Listing (<code class="inline-code">#list</code>) has received some
specialized convenience features that target typical tasks
people do again and again in templates.</p>
<ul>
<li>
<p>New <code class="inline-code">list</code> directive child
directives. There are <code class="inline-code">else</code> and
<code class="inline-code">items</code> to deal with special cases with
0-length lists, and <code class="inline-code">sep</code> for inserting
separators between items. For more details, see the <a href="ref_directive_list.html"><code>list</code>
directive in the Reference</a>.</p>
</li>
<li>
<p><a href="ref_builtins_loop_var.html">New built-ins
that act on loop variables</a>:
<code class="inline-code"><em class="code-color">var</em>?index</code>
(deprecates
<code class="inline-code"><em class="code-color">var</em>_index</code>),
<code class="inline-code"><em class="code-color">var</em>?counter</code>
(1-based index),
<code class="inline-code"><em class="code-color">var</em>?has_next</code>
(deprecates
<code class="inline-code"><em class="code-color">var</em>_has_next</code>),
<code class="inline-code"><em class="code-color">var</em>?is_first</code>,
<code class="inline-code"><em class="code-color">var</em>?is_last</code>,
<code class="inline-code"><em class="code-color">var</em>?item_parity</code>
(returns <code class="inline-code">&quot;odd&quot;</code> or
<code class="inline-code">&quot;even&quot;</code>),
<code class="inline-code"><em class="code-color">var</em>?item_parity_cap</code>,
<code class="inline-code"><em class="code-color">var</em>?item_cycle</code><code class="inline-code">(<em class="code-color">...</em>)</code>,
etc.</p>
</li>
</ul>
</li>
<li>
<p>Added convenience assignment operators, which can be used
in assignment directives (<code class="inline-code">#assign</code>,
<code class="inline-code">#global</code> and <code class="inline-code">#local</code>
currently) only:</p>
<ul>
<li>
<p><code class="inline-code">++</code> and <code class="inline-code">--</code>: For
example, <code class="inline-code">&lt;#assign counter++&gt;</code> is
equivalent to <code class="inline-code">&lt;#assign counter = counter +
1&gt;</code>.</p>
</li>
<li>
<p><code class="inline-code">+=</code>, <code class="inline-code">-=</code>,
<code class="inline-code">*=</code>, <code class="inline-code">/=</code> and
<code class="inline-code">%=</code>: For example, <code class="inline-code">&lt;#assign
counter += 2&gt;</code> is equivalent to
<code class="inline-code">&lt;#assign counter = counter +
2&gt;</code>.</p>
</li>
</ul>
</li>
<li>
<p>Added the <code class="inline-code">then</code> built-in, which can be
used like a ternary operator:
<code class="inline-code"><em class="code-color">someBoolean</em>?then(<em class="code-color">whenTrue</em>,
<em class="code-color">whenFalse</em>)</code>. Just like with
the ternary operator of most other languages, only one of the
parameter expressions will be evaluated. <a href="ref_builtins_boolean.html#ref_builtin_then">More details...</a></p>
</li>
<li>
<p>Added the <code class="inline-code">switch</code> built-in, which can be
used like an in-line (expression) switch-case-default statement:
<code class="inline-code"><em class="code-color">someValue</em>?switch(<em class="code-color">case1</em>,
<em class="code-color">result1</em>,
<em class="code-color">case2</em>,
<em class="code-color">result2</em>, ...
<em class="code-color">caseN</em>,
<em class="code-color">resultN</em>,
<em class="code-color">defaultResult</em>)</code>, where
<code class="inline-code"><em class="code-color">defaultResult</em></code> can
be omitted (then it will be error if none of the cases matches).
<a href="ref_builtins_type_independent.html#ref_builtin_switch">More details...</a></p>
</li>
<li>
<p>Added camel case support for the identifiers that are part
of the template language (user defined names aren&#39;t affected).
For example, now
<code class="inline-code">&lt;#noEscape&gt;${x?upperCase}&lt;/#noEscape&gt;</code>
or <code class="inline-code">&lt;#setting numberFormat=&quot;0.0&quot;&gt;</code> or
<code class="inline-code">&lt;#ftl stripText=true&gt;</code> are valid.
However, within the same template, FreeMarker will require you
to use the same naming convention consistently for all
identifiers that are part of the template language. It&#39;s also
possible to enforce the same naming convention on all templates
from Java via
<code class="inline-code">Configuration.setNamingConvention(int)</code>. It&#39;s
certain that camel case will be the recommended convention
starting from some future version, because the Java API-s users
call from templates use that too.</p>
</li>
<li>
<p>Added new <a href="ref_specvar.html">special
variables</a>, <code class="inline-code">.current_template_name</code> and
<code class="inline-code">.main_template_name</code>. These deprecate
<code class="inline-code">.template_name</code>, which was always broken when
it comes to macro calls. The new
<code class="inline-code">.current_template_name</code> always returns the
name of the template that contains the reference to the special
variable, and <code class="inline-code">.main_template_name</code> always
returns the name of the topmost template.</p>
</li>
<li>
<p>Smaller error message improvements. Like, added tip in the
error message for the frequent issue when
<code class="inline-code"><em class="code-color">someMap</em>[<em class="code-color">someNumber</em>]</code>
complains that
<code class="inline-code"><em class="code-color">someMap</em></code> is not a
sequence nor is coercible to string.</p>
</li>
<li>
<p>Bug fixed, activated with setting
<code class="inline-code">incompatible_improvements</code> to 2.3.23: There&#39;s
a long existing parse-time rule that says that
<code class="inline-code">#break</code>, in the FTL source code itself, must
occur nested inside a breakable directive, such as
<code class="inline-code">#list</code> or <code class="inline-code">#switch</code>. This
check could be circumvented with <code class="inline-code">#macro</code> or
<code class="inline-code">#function</code>, like this: <code class="inline-code">&lt;#list 1..1
as x&gt;&lt;#macro
callMeLater&gt;&lt;#break&gt;&lt;/#macro&gt;&lt;/#list&gt;&lt;@callMeLater
/&gt;</code>. After activating this fix, this will be caught
as parse time error.</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_173">Changes on the Java side</h2>
<ul>
<li>
<p>Added
<code class="inline-code">Configuration.setNamingConvention(int)</code>. By
default FreeMarker will auto-detect the naming convention
(legacy VS camel case) used for the identifiers that are part of
the template language, for each template independently. This
setting lets you enforce a naming convention instead.</p>
</li>
<li>
<p><code class="inline-code">Configuration</code> (and in fact any
<code class="inline-code">Configurable</code>) setting names now can be
written with camel case as well. For example, if you are
configuring FreeMarker from properties file, you can have
<code class="inline-code">defaultEncoding=utf-8</code> instead of
<code class="inline-code">default_encoding=utf-8</code>. You can use the two
naming conventions (camel case, and tradition snake case) mixed,
and <code class="inline-code">Configuration.setNamingConvention(int)</code>
does not influence this behavior.</p>
</li>
<li>
<p>Added
<code class="inline-code">Configuration.setTemplateUpdateDelayMilliseconds(long)</code>
and
<code class="inline-code">Configuration.getTemplateUpdateDelayMilliseconds()</code>.
This deprecates <code class="inline-code">setTemplateUpdateDelay(int)</code>,
which uses seconds resolution, hence going against Java
conventions and often leading to misunderstandings. (Also that
couldn&#39;t have a getter pair.)</p>
</li>
<li>
<p>The <code class="inline-code">template_update_delay</code> setting, when
specified as a string (as inside
<code class="inline-code">java.util.Properties</code>), supports time units,
like in <code class="inline-code">template_update_delay=500 ms</code>.</p>
</li>
<li>
<p>Added <code class="inline-code">Environment.getCurrentTemplate()</code>
method, which return the currently executed template (as opposed
to the main template).</p>
</li>
<li>
<p>Added
<code class="inline-code">WebappTemplateLoader.setAttemptFileAccess(boolean)</code>,
which can be used to disable the legacy trick where we try to
load templates through direct file access, so that template
updating works without restarting. Disabling URL connection
caches
(<code class="inline-code">someURLBasedTemplateLoader.setURLConnectionUsesCaches(false)</code>,
which is also the default since
<code class="inline-code">incompatible_improvements</code> 2.3.21) probably
solves that on modern Servlet containers.</p>
</li>
<li>
<p>In the <code class="inline-code">FreemarkerServlet</code>
<code class="inline-code">TemplatePath</code> init-param, paths (like
<code class="inline-code">/templates</code>) can have a
<code class="inline-code">?settings(<em class="code-color">...</em>)</code>
postfix, with which you can set the JavaBean properties of the
resulting <code class="inline-code">TemplateLoader</code>. For example:
<code class="inline-code">&lt;param-value&gt;/templates?settings(attemptFileAccess=false,
URLConnectionUsesCaches=false)&lt;/param-value&gt;</code></p>
</li>
<li>
<p>Added
<code class="inline-code">FileTemplateLoader.setEmulateCaseSensitiveFileSystem(boolean)</code>.
This is handy when you are developing on Windows but will deploy
to a platform with case sensitive file system. The default is
<code class="inline-code">false</code>, and <code class="inline-code">true</code> is only
meant for development, not for production installations. The
default can be overridden by setting the
<code class="inline-code">org.freemarker.emulateCaseSensitiveFileSystem</code>
system property to <code class="inline-code">true</code>.</p>
</li>
<li>
<p>Bug fixed [<a href="https://sourceforge.net/p/freemarker/bugs/424">424</a>]:
<code class="inline-code">WebappTemplateLoader</code> didn&#39;t find templates
that are stored in
<code class="inline-code">WEB-INF/lib/*.jar/META-INF/resources</code>. Files
under that directory are visible as
<code class="inline-code">ServletContext</code> resources since Servlet 3.0,
yet <code class="inline-code">WebappTemplateLoader</code> has usually failed
to see them because of some internal tricks.</p>
</li>
<li>
<p>Bug fixed: If a template "file" was
successfully opened for reading, but then there was an
<code class="inline-code">IOException</code> during reading its content, the
parser (JavaCC) acted like if the template "file"
was ended there, and the exception was suppressed. It&#39;s actually
a JavaCC quirk that affects many other JavaCC-based languages
too, but now FreeMarker has added a workaround in the
<code class="inline-code">Template</code> constructor, and so now an exception
will be thrown as expected.</p>
</li>
<li>
<p>Bug fixed:
<code class="inline-code">InvalidReferenceException.FAST_INSTANCE</code> could
accidentally store reference to an
<code class="inline-code">Environment</code> instance, which hence was never
garbage collected.</p>
</li>
<li>
<p>Bug fixed [<a href="https://sourceforge.net/p/freemarker/bugs/426/">426</a>]:
When setting <code class="inline-code">incompatible_improvements</code> to
2.3.22, the special variable reference
<code class="inline-code">.template_name</code> in templates always returns
the name of the main (topmost) template, due to an oversight in
2.3.22. Setting <code class="inline-code">incompatible_improvements</code> to
2.3.23 restores the old, backward compatible behavior. (Note
that the old behavior that we emulate is itself broken, as it
doesn&#39;t work well with macro calls; you should use
<code class="inline-code">.current_template_name</code> or
<code class="inline-code">.main_template_name</code> instead.)</p>
</li>
<li>
<p>Bug fixed [<a href="https://sourceforge.net/p/freemarker/bugs/53/">53</a>]:
Template parsing was abnormally slow for templates with very
high number AST (abstract syntax tree) nodes on the same
hierarchy level.</p>
</li>
<li>
<p>Bug fixed: When the template was concurrently replaced on
the backing store during its first loading was still ongoing,
the older version of the template could get into the cache with
the time stamp of the new version, hence it wasn&#39;t reloaded
after the configured update delay.</p>
</li>
<li>
<p>Bug fixed: The <code class="inline-code">log_template_exceptions</code>
setting (added in 2.3.22) couldn&#39;t be set through the
<code class="inline-code">Configurable.setSetting(String, String)</code>
API.</p>
</li>
<li>
<p>Bug fixed:
<code class="inline-code">StringUtil.FTLStringLiteralEnc</code> has escaped
<code class="inline-code">$</code> (hence generating an illegal escape) and
haven&#39;t escaped <code class="inline-code">{</code> after <code class="inline-code">$</code>
and <code class="inline-code">#</code>. While this function is only used for
generating error messages by FreeMarker, it&#39;s a public methods
so anyone could use it.</p>
</li>
<li>
<p>Bugs fixed: Various canonical form glitches (they only
affect error messages as far as FreeMarker is concerned).</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_174">Other changes</h2>
<ul>
<li>
<p>Modernized Manual and site design with improved
functionality (always visible navigation tree, search inside the
Manual, etc.), thanks to Evangelia Dendramis. (Also now the Site
uses the same format and HTML generator as the Manual.)</p>
</li>
<li>
<p>Many smaller Manual and site content
updates/improvements.</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_175">Notes</h2>
<p>Changes compared to 2.3.23 RC1:</p>
<ul>
<li>
<p><code class="inline-code">.current_name_name</code> and
<code class="inline-code">.main_template_name</code> is now missing
(<code class="inline-code">null</code>) instead of <code class="inline-code">&quot;&quot;</code> if
the template has no name</p>
</li>
<li>
<p>Some minor error message improvements</p>
</li>
<li>
<p>Documentation refinements</p>
</li>
</ul>
<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="versions_2_3_24.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3_22.html"><span>Next</span></a></div></div></div></div> </div>
</div>
<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"><div class="column"><h3 class="column-header">Overview</h3><ul><li><a href="https://freemarker.apache.org/">What is FreeMarker?</a></li><li><a href="https://freemarker.apache.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="app_faq.html">FAQ</a></li><li><a itemprop="license" href="app_license.html">License</a></li><li><a href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy policy</a></li></ul></div><div class="column"><h3 class="column-header">Often used / Reference</h3><ul><li><a href="https://try.freemarker.apache.org/">Try template online</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions cheatsheet</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_builtins_alphaidx.html">?built_ins</a></li><li><a href="ref_specvar.html">.special_vars</a></li><li><a href="api/freemarker/core/Configurable.html#setSetting-java.lang.String-java.lang.String-">Configuration settings</a></li></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href="https://github.com/apache/freemarker">Github project page</a></li><li><a href="https://issues.apache.org/jira/projects/FREEMARKER">Report a bug</a></li><li><a href="https://freemarker.apache.org/report-security-vulnerabilities.html">Report security vulnerability</a></li><li><a href="https://stackoverflow.com/questions/ask?tags=freemarker">Get help on StackOverflow</a></li><li><a href="https://twitter.com/freemarker">Announcements on Twitter</a></li><li><a href="https://freemarker.apache.org/mailing-lists.html">Discuss on mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/apache/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="https://stackoverflow.com/questions/ask?tags=freemarker">Stack Overflow</a></li></ul><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
Last generated:
<time itemprop="dateModified" datetime="2024-02-12T20:34:04Z" title="Monday, February 12, 2024 at 8:34:04 PM Greenwich Mean Time">2024-02-12 20:34:04 GMT</time>, for Freemarker 2.3.32 </p>
<p class="copyright">
© <span itemprop="copyrightYear">1999</span>–2024
<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a>. Apache FreeMarker, FreeMarker, Apache Incubator, Apache, the Apache FreeMarker logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners. </p>
</div></div></div></body>
</html>