blob: 511dc7d00a0430c4deed0b01469d424e625ba3b3 [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.28 - 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.28">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="https://freemarker.apache.org/docs/versions_2_3_28.html">
<link rel="canonical" href="https://freemarker.apache.org/docs/versions_2_3_28.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_28.html"><span itemprop="name">2.3.28</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.28"];</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_29.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3_27.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="versions_2_3_28" itemprop="headline">2.3.28</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#autoid_158" data-menu-target="autoid_158">Changes on the FTL side</a></li><li><a class="page-menu-link" href="#autoid_159" data-menu-target="autoid_159">Changes on the Java side</a></li><li><a class="page-menu-link" href="#autoid_160" data-menu-target="autoid_160">Other changes</a></li></ul> </div><p>Release date: 2018-04-04</p>
<h2 class="content-header header-section2" id="autoid_158">Changes on the FTL side</h2>
<ul>
<li>
<p>Added new <a href="ref_specvar.html">special
variable</a>, <code class="inline-code">get_optional_template</code> (<a href="https://issues.apache.org/jira/browse/FREEMARKER-84">FREEMARKER-84</a>).
It can be used when you need to include or import a template
that&#39;s possibly missing, and you need to handle that case on
some special way. <a href="ref_specvar.html#ref_specvar_get_optional_template">See the details
here...</a></p>
</li>
<li>
<p>Added new <a href="ref_specvar.html">special
variable</a>, <code class="inline-code">caller_template_name</code> (<a href="https://issues.apache.org/jira/browse/FREEMARKER-83">FREEMARKER-83</a>),
which returns the name (path) of the template from which the
current macro or function was called. It&#39;s mostly useful if you
want to resolve paths relative to the caller template.</p>
</li>
<li>
<p>Added new built-in,
<code class="inline-code"><em class="code-color">templateName</em>?absolute_template_name</code>
or
<code class="inline-code"><em class="code-color">templateName</em>?absolute_template_name(<em class="code-color">baseName</em>)</code>,
which can be used to convert a relative template name to an
absolute template name. <a href="ref_builtins_expert.html#ref_builtin_absolute_template_name">See more
here...</a></p>
</li>
<li>
<p>Added new built-ins:
<code class="inline-code"><em class="code-color">sequence</em>?min</code> and
<code class="inline-code"><em class="code-color">sequence</em>?max</code>
(<a href="https://issues.apache.org/jira/browse/FREEMARKER-86">FREEMARKER-86</a>),
which return the smallest and greatest item from a list of
numbers or date/time/date-times. <a href="ref_builtins_sequence.html#ref_builtin_min_max">See more here...</a></p>
</li>
<li>
<p>The template language can now be configured to use
<code class="inline-code">[=<em class="code-color">expression</em>]</code>
instead of
<code class="inline-code">${<em class="code-color">expression</em>}</code> and
<code class="inline-code">#{<em class="code-color">expression</em>}</code>,
which is very useful if you have a lot of
<code class="inline-code">${<em class="code-color">...</em>}</code> or
<code class="inline-code">#{<em class="code-color">...</em>}</code> in the text
that you are generating, and so they should be static text. See
<a href="dgui_misc_alternativesyntax.html#dgui_misc_alternativesyntax_interpolation">more
about the square bracket interpolation syntax here.</a> The
template language can also be configured to only use
<code class="inline-code">${<em class="code-color">expression</em>}</code>, and
treat
<code class="inline-code">#{<em class="code-color">expression</em>}</code> as
static text. (See the <code class="inline-code">interpolation_syntax</code>
configuration setting, or the
<code class="inline-code">Configuration.setInterpolationSyntax(int)</code>
method.)</p>
</li>
<li>
<p>In string literals, <code class="inline-code">\=</code> is now a valid
escape sequence, resulting in a <code class="inline-code">=</code>. This is
useful when you are using the new
<code class="inline-code">[=<em class="code-color">exp</em>]</code>
interpolation syntax, which can be escaped in a string literal
like <code class="inline-code">&quot;Literal [\=x]&quot;</code>.</p>
</li>
<li>
<p>Bug fixed (<a href="https://issues.apache.org/jira/browse/FREEMARKER-83">FREEMARKER-83</a>);
this fix is only active when <a href="pgui_config_incompatible_improvements.html#pgui_config_incompatible_improvements_how_to_set"><code>incomplatible_improvements</code></a>
is set to 2.3.28 (or higher). When calling a macro or function
(things defined in a template, not directly in Java) and the
argument list contains
<code class="inline-code">.current_template_name</code>, now it will correctly
evaluate to the template that contains the call, rather than to
the template that contains the macro or function definition. (Of
course, the parameter default value expression is still
evaluated in the context of the called macro or
function.)</p>
</li>
<li>
<p>Bug fixed: When
<code class="inline-code"><em class="code-color">string</em>?split(<em class="code-color">separator</em>)</code>
is called with <code class="inline-code">&quot;&quot;</code> as the argument, the string
will be split to characters now. Earlier it has thrown an
<code class="inline-code">IllegalArgumentException</code> (unless the
<code class="inline-code">r</code> flag was specified).</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_159">Changes on the Java side</h2>
<ul>
<li>
<p>Added new <code class="inline-code">ParserConfiguration</code> (such as
<code class="inline-code">Configuration</code> and
<code class="inline-code">TemplateConfiguration</code>) setting,
<code class="inline-code">interpolation_syntax</code>. It has 3 possible
values:</p>
<ul>
<li>
<p><code class="inline-code">legacy</code> (the default):
Interpolations look like
<code class="inline-code">${<em class="code-color">...</em>}</code> or
<code class="inline-code">#{<em class="code-color">...</em>}</code>. Note
that <code class="inline-code">#{<em class="code-color">...</em>}</code> is
deprecated for a long time now.</p>
</li>
<li>
<p><code class="inline-code">dollar</code>: Interpolations look like
<code class="inline-code">${<em class="code-color">...</em>}</code>. With
this syntax,
<code class="inline-code">#{<em class="code-color">...</em>}</code> will be
just static text.</p>
</li>
<li>
<p><code class="inline-code">square_bracket</code>: Interpolations look
like <code class="inline-code">[=<em class="code-color">...</em>]</code>.
With this syntax
<code class="inline-code">${<em class="code-color">...</em>}</code> and
<code class="inline-code">#{<em class="code-color">...</em>}</code> will be
just static text. So it&#39;s useful if you generate output in a
format where those (typically
<code class="inline-code">${<em class="code-color">...</em>}</code>) are
already used, such as to generate JSP pages, or to generate
FreeMarker templates that use the default syntax.</p>
</li>
</ul>
</li>
<li>
<p>When specifying the <code class="inline-code">output_format</code>
configuration setting with
<code class="inline-code">String</code>-<code class="inline-code">String</code> key-value
pairs (like with <code class="inline-code">Configuration.setSetting(String,
String)</code> or in a <code class="inline-code">.properties</code> file),
it&#39;s now possible to specify the standard output formats by
short name (like <code class="inline-code">output_format=HTML</code>) rather
than by class name. (Custom formats still has to be referred by
class name, as FreeMarker can&#39;t discover what their names are,
since it&#39;s not aware of the custom classes.)</p>
</li>
<li>
<p>Added a new
<code class="inline-code">Configuration.removeTemplateFromCache</code>
overload that has a <code class="inline-code">Object
customLookupCondition</code> parameter. This is useful to
manually evacuate a template from the cache that was get with a
non-<code class="inline-code">null</code> custom lookup condition.</p>
</li>
<li>
<p>Added new property to
<code class="inline-code">BeansWrapper.MethodAppearanceDecision</code>:
<code class="inline-code">replaceExistingProperty</code>. This is useful when
a method like <code class="inline-code">size()</code> is exposed as a JavaBean
property via
<code class="inline-code">MethodAppearanceDecision.exposeAsProperty</code>,
but there&#39;s also a "real" JavaBean property (like
<code class="inline-code">getSize()</code>) with identical name. By default
the real property isn&#39;t replaced, but now with
<code class="inline-code">replaceExistingProperty</code> it can be.</p>
</li>
<li>
<p><code class="inline-code">DirectiveCallPlace</code> now has a
<code class="inline-code">Template getTemplate()</code> method, so you can
query if from which template was your
<code class="inline-code">TemplateDirectiveModel</code> called. (This has
similar role as <code class="inline-code">.caller_template_name</code> for
macros/functions.)</p>
</li>
<li>
<p>Added
<code class="inline-code">Environment.rootBasedToAbsoluteTemplateName(String)</code>,
which converts the root based names typically used for the
FreeMarker Java API-s (such as
<code class="inline-code">Configuration.getTemplate(name)</code>) to an
absolute path, which can be safely passed to
<code class="inline-code">&lt;#include
<em class="code-color">path</em>&gt;</code> and such, as it
won&#39;t be misinterpreted to be relative to the directory of the
template.</p>
</li>
<li>
<p>Fixes in exception handling when calling JSP tags:</p>
<ul>
<li>
<p>Bug fixed (<a href="https://issues.apache.org/jira/browse/FREEMARKER-88">FREEMARKER-88</a>):
If a <code class="inline-code">TemplateException</code> that&#39;s not a
<code class="inline-code">TemplateModelExceptoin</code> has occurred in
the body (nested content) of a JSP
<code class="inline-code">SimpleTag</code> (typically, an
<code class="inline-code">InvalidReferenceException</code>), that has
caused a <code class="inline-code">ClassCastException</code> in the
exception handling code, thus the template processing has
thrown that instead of the original exception.</p>
</li>
<li>
<p>Bug fixed: For JSP Tag based custom tags, if an
exception has occurred in the body (nested content), an
<code class="inline-code">IndexOutOfBoundsException</code> might have
occurred, replacing the original exception.</p>
</li>
<li>
<p>Wrapping of
non-<code class="inline-code">TemplateModelException</code>
<code class="inline-code">TemplateException</code>-s (typically
<code class="inline-code">InvalidReferenceException</code>-s) into
<code class="inline-code">TemplateModelException</code>-s is now avoided
when the <code class="inline-code">TemplateException</code> occurs in the
body of a JSP tag.</p>
</li>
</ul>
</li>
<li>
<p>The default arithmetic engine
(<code class="inline-code">ArithmeticEngine.BIGDECIMAL_ENGINE</code>) can now
compare infinite (both positive and negative) to any other
standard numerical type. Earlier, since
<code class="inline-code">BigDecimal</code> can&#39;t represent infinite, it was
only working in certain special cases. Also there were some
performance optimizations to slightly decrease the impact and
number of conversions to <code class="inline-code">BigDecimal</code>.</p>
</li>
<li>
<p>Avoided possible performance bottleneck when executing
templates on many threads, caused by that
<code class="inline-code">java.beans.PropertyDescriptor.getReadMethod()</code>
is synchronized (<a href="https://issues.apache.org/jira/browse/FREEMARKER-80">FREEMARKER-80</a>).</p>
</li>
<li>
<p>Added
<code class="inline-code">TemplateModelUtils.getKeyValuePairIterator(TemplateHashModelEx)</code>
static utility class, which can be used to get a
<code class="inline-code">TemplateHashModelEx2.KeyValuePairIterator</code>
even for a non-<code class="inline-code">TemplateHashModelEx2</code> object.
This simplifies Java code that iterates through key-value
pairs.</p>
</li>
<li>
<p><code class="inline-code">freemarker.template.utility.DeepUnwrap</code>
(a rarely used utility) now utilizes when the unwrapped
<code class="inline-code">TemplateModel</code> implements
<code class="inline-code">TemplateHashModelEx2.getKeyValuePairIterator()</code>,
and thus can unwrap such a hash value even if it has non-string
keys. Also, it nows keeps the iteration order of the hashes, as
it unwraps into a <code class="inline-code">LinkedHashMap</code> instead of
into a plain <code class="inline-code">HashMap</code>.</p>
</li>
<li>
<p><code class="inline-code">freemarker.ext.beans.HashAdapter.size()</code>
was overridden for better performance.</p>
</li>
<li>
<p>When the <a href="pgui_config_incompatible_improvements.html#pgui_config_incompatible_improvements_how_to_set"><code>incompatible_improvements</code>
setting</a> is set to 2.3.28 (or greater): Fixed legacy
parser glitch where a tag can be closed with an illegal
<code class="inline-code">]</code> (when it&#39;s not part of an expression)
despite that the tag syntax is set to angle brackets. For
example <code class="inline-code">&lt;#if x]</code> worked just like
<code class="inline-code">&lt;#if x&gt;</code>. Note that this legacy glitch
didn&#39;t affect the legal usage of <code class="inline-code">]</code>, like
<code class="inline-code">&lt;#if x[0]&gt;</code> has always worked
correctly.</p>
</li>
<li>
<p>Fixed parser bug that disallowed using
<code class="inline-code">&gt;</code> as the top-level expression inside an
interpolation (<code class="inline-code">${...}</code>). It had the same
reason why <code class="inline-code">&lt;#if x &gt; y&gt;</code> doesn&#39;t work
as naively expected, but there&#39;s no real ambiguity in
<code class="inline-code">${x &gt; y}</code>, so now it&#39;s allowed. Note that
<code class="inline-code">${(x &gt; y)?c}</code> and <code class="inline-code">${(x &gt;
y)?string(&#39;y&#39;, &#39;n&#39;)}</code>, which are how booleans are
commonly printed, have always worked, as the
<code class="inline-code">&gt;</code> operation is not on the top-level inside
the interpolation.</p>
</li>
<li>
<p>Fixed incorrect listing of valid
<code class="inline-code">roundingMode</code>-s in <a href="ref_builtins_number.html#topic.extendedJavaDecimalFormat">extended Java decimal
format</a> parsing error message</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_160">Other changes</h2>
<ul>
<li>
<p>FreeMarker has graduated from the Apache Incubator (as of
2018-03-21), and now is a normal top-level project at Apache.
Therefore, the version number doesn&#39;t contain
"-incubating" anymore.</p>
</li>
</ul>
<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="versions_2_3_29.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3_27.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>