blob: 3adf3b625f0693e623abfd0e51373495d5600199 [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.24 (incubating at Apache) - 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.24 (incubating at Apache)">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="https://freemarker.apache.org/docs/versions_2_3_24.html">
<link rel="canonical" href="https://freemarker.apache.org/docs/versions_2_3_24.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_24.html"><span itemprop="name">2.3.24 (incubating at Apache)</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.24 (incubating at Apache)"];</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_25.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3_23.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="versions_2_3_24" itemprop="headline">2.3.24 (incubating at Apache)</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#autoid_168" data-menu-target="autoid_168">Legal changes</a></li><li><a class="page-menu-link" href="#autoid_169" data-menu-target="autoid_169">Changes on the FTL side</a></li><li><a class="page-menu-link" href="#autoid_170" data-menu-target="autoid_170">Changes on the Java side</a></li><li><a class="page-menu-link" href="#autoid_171" data-menu-target="autoid_171">Changes compared to 2.3.24 Release Candidate 1</a></li></ul> </div><p>Release date: 2016-03-28</p><p><strong>This is a stable, final
release.</strong> The "incubating" suffix is required
by the Apache Software Foundation until the project becomes a fully
accepted (graduated) Apache project. See disclaimer below.</p>
<h2 class="content-header header-section2" id="autoid_168">Legal changes</h2>
<p>The owner of FreeMarker is now the Apache Software Foundation.
The license is still Apache License Version 2.0, just like earlier,
but the owner is different. The official full product name has
changed to Apache FreeMarker.</p>
<h2 class="content-header header-section2" id="autoid_169">Changes on the FTL side</h2>
<ul>
<li>
<p>The most important new feature of this release is the
<a href="dgui_misc_autoescaping.html">auto-escaping and output
formats mechanism</a>, which deprecates escaping with the
<a href="ref_directive_escape.html"><code>escape</code>
directive</a>. These are the changes related to this new
mechanism (see earlier link for a guide):</p>
<ul>
<li>
<p>New <code class="inline-code">ftl</code> header options,
<code class="inline-code">ouput_format</code> and
<code class="inline-code">auto_esc</code> to override the
<code class="inline-code">output_format</code> and
<code class="inline-code">auto_escaping</code> settings of the template,
like <code class="inline-code">&lt;#ftl
output_format=&#39;HTML&#39;</code><code class="inline-code">
auto_esc=false&gt;</code>.</p>
</li>
<li>
<p>New built-in: <a href="ref_builtins_string.html#ref_builtin_no_esc"><code>no_esc</code></a>.
Used to prevent auto-escaping, like
<code class="inline-code">${descriptionInHtml?no_esc}</code>. This doesn&#39;t
work with <code class="inline-code">&lt;#escape
<em class="code-color">...</em>&gt;</code>, only with the
new auto-escaping mechanism.</p>
</li>
<li>
<p>New FTL type, "markup output". This is
somewhat similar to string, but values of this type aren&#39;t
auto-escaped by the new escaping mechanism, because they are
known to already hold markup. (For example,
<code class="inline-code">?esc</code> and <code class="inline-code">?no_esc</code>
returns a value of this type, hence their results are
protected from double-escaping problems.)</p>
</li>
<li>
<p>New built-in: <a href="ref_builtins_string.html#ref_builtin_esc"><code>esc</code></a>.
Used for escaping with the current output format when
auto-escaping is disabled.</p>
</li>
<li>
<p>New built-in: <code class="inline-code">markup_string</code>. This
returns the markup of a <a href="dgui_misc_autoescaping.html#dgui_misc_autoescaping_movalues">markup output
value</a> as string.</p>
</li>
<li>
<p>New built-in: <code class="inline-code">is_markup_output</code>,
returns <code class="inline-code">true</code> if the value is of type
"markup output".</p>
</li>
<li>
<p>New directive: <code class="inline-code">outputformat</code>, used
to change the output format for a section of a template,
like <code class="inline-code">&lt;#outputformat
&quot;XML&quot;&gt;<em class="code-color">...</em>&lt;/#outputformat&gt;</code></p>
</li>
<li>
<p>New directives: <code class="inline-code">noautoesc</code> and
<code class="inline-code">autoesc</code>, used to turn auto-escaping off
and on for a section of a template, like
<code class="inline-code">&lt;#noautoesc&gt;<em class="code-color">...</em>&lt;/#noautoesc&gt;</code>.</p>
</li>
<li>
<p>New built-in variable,
<code class="inline-code">.output_format</code>, returns the current
output format at the place of invocation.</p>
</li>
<li>
<p>New built-in variable, <code class="inline-code">.auto_esc</code>,
returns the boolean that tells if auto-escaping is active at
the place of invocation.</p>
</li>
<li>
<p>Block assignments, like <code class="inline-code">&lt;#assign
<em class="code-color">captured</em>&gt;<em class="code-color">...</em>&lt;/#assign&gt;</code>,
when the current <code class="inline-code">output_format</code> is some
kind of markup (like HTML), will store the captured output
not with string type, but with "markup output"
type. Thus
<code class="inline-code">${<em class="code-color">captured</em>}</code>
will not get unwanted escaping.</p>
</li>
<li>
<p>The <code class="inline-code">+</code> operator (concatenation)
works with the new "markup output" type as
well. Like <code class="inline-code">someMarkup + somePlainText</code>
will result in markup where <code class="inline-code">somePlainText</code>
is escaped automatically before it&#39;s appended to the
markup.</p>
</li>
<li>
<p>The <code class="inline-code">has_content</code> built-in now
supports "markup output" values, considering 0
length markup as empty.</p>
</li>
</ul>
</li>
<li>
<p>You can now define custom number and date/time/datetime
formatters. These are defined by the programmers (and thus can
implement any kind of exotic formatting rules) when configuring
FreeMarker, and can be referred with strings starting with
<code class="inline-code">&quot;@&quot;</code>, like in <code class="inline-code">&lt;#setting
number_format=&#39;@foo&#39;&gt;</code>, or
<code class="inline-code">${n?string.@foo_params}</code>,
<code class="inline-code">&lt;#setting number_format=&#39;@foo params&#39;&gt;</code>,
or <code class="inline-code">${n?string.@foo}</code>,
<code class="inline-code">${n?string.@foo_params}</code>. For backward
compatibility, the initial <code class="inline-code">@</code> only has this
special meaning if either you have any custom formats or <a href="pgui_config_incompatible_improvements.html">the
<code>incompatible_improvements</code> setting</a> is
at lest 2.3.24.</p>
</li>
<li>
<p>Everywhere where Java <code class="inline-code">DecimalFormat</code>
patterns are used (like in <code class="inline-code">?string(&#39;0.##&#39;)</code> or
<code class="inline-code">&lt;#setting number_format=&quot;0.##&quot;&gt;</code>), now
it&#39;s possible to specify options like rounding mode or the
symbols used, with a FreeMarker-specific <a href="ref_builtins_number.html#topic.extendedJavaDecimalFormat">extension to the
<code>DecimalFormat</code> pattern syntax</a>.</p>
</li>
<li>
<p>Added new special variable:
<code class="inline-code">.incompatible_improvements</code>, which returns the
<a href="pgui_config_incompatible_improvements.html"><code>incompatible_improvements</code>
setting</a> of the current FreeMarker configuration, as a
string.</p>
</li>
<li>
<p><code class="inline-code">?date</code>, <code class="inline-code">?time</code> and
<code class="inline-code">?datetime</code> now can be called as 0 argument
method, like <code class="inline-code">?date()</code>, etc., which returns the
exact object that <code class="inline-code">TemplateDateFormat.parse</code>
returns, instead of the tricky multi-type object that just using
<code class="inline-code">?date</code> returns. Because custom
<code class="inline-code">TemplateDateFormat</code> implementations may return
custom <code class="inline-code">TemplateDateModel</code> implementations,
keeping the exact class can be important in some
applications.</p>
</li>
<li>
<p><code class="inline-code">&lt;@</code> and <code class="inline-code">&lt;/@</code> is
now allowed in string literals that contain
<code class="inline-code">${<em class="code-color">exp</em>}</code>, and will
be part of the literal as is. Earlier it was a syntactical
error.</p>
</li>
<li>
<p>Bug fixed: With
<code class="inline-code">incompatible_improvements</code> set to 2.3.24
(<a href="pgui_datamodel_objectWrapper.html#topic.defaultObjectWrapperIcI">see how
here...</a>),
<code class="inline-code"><em class="code-color">m</em>?is_sequence</code>
doesn&#39;t return <code class="inline-code">true</code> for Java methods wrapped
by <code class="inline-code">BeansWrapper</code> and its subclasses (most
notably <code class="inline-code">DefaultObjectWrapper</code>) anymore, as
they only implement the
<code class="inline-code">[<em class="code-color">index</em>]</code> operator,
but not <code class="inline-code">?size</code>, which causes
<code class="inline-code">&lt;#list <em class="code-color">...</em>&gt;</code>
to fail, among others.</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_170">Changes on the Java side</h2>
<ul>
<li>
<p><em>Attention!</em> FreeMarker
now requires at least Java 1.5 (aka. Java 5). 2.3.24 has only
required Java 1.4. (Reason: Without this, new public API-s
couldn&#39;t use generics, which affect negatively the majority of
users, while old installations that are still using 1.4 are
unlikely to update FreeMarker anyway.)</p>
</li>
<li>
<p><em>Attention!</em> FreeMarker&#39;s
JSP support (if it&#39;s used) now requires at least JSP 2.0.
Earlier it only required JSP 1.1. (Reason: The
<code class="inline-code">jsp-api</code> dependency for JSP 1.x, which was
needed for building, can&#39;t be legally present in the Maven
Central Repository, nor be provided by freemarker.org.)</p>
</li>
<li>
<p>Added new configuration setting:
<code class="inline-code">template_configurations</code>. This allows
overriding the settings coming from the shared
<code class="inline-code">Configuration</code> object for individual
templates, based on template name patterns. <a href="pgui_config_templateconfigurations.html">See more
here...</a></p>
</li>
<li>
<p>Related to the <a href="dgui_misc_autoescaping.html">new
auto-escaping mechanism</a>:</p>
<ul>
<li>
<p>As FTL has now a new type, "markup
output", there&#39;s also a corresponding new model
interface, <code class="inline-code">TemplateMarkupOutputModel</code>.
This also means that you can prevent the auto-escaping of
values coming from the data-model by returning a
<code class="inline-code">TemplateMarkupOutputModel</code> instead of a
<code class="inline-code">String</code>. Like the template author can just
write <code class="inline-code">${messages.foo}</code>, and it will be
auto-escaped or not depending on if the message is known to
be markup or not.</p>
</li>
<li>
<p>Added new configuration setting:
<code class="inline-code">recognize_standard_file_extensions</code>. When
<code class="inline-code">true</code>, templates whose source name ends
with <code class="inline-code">&quot;.ftlh&quot;</code> will get
<code class="inline-code">HTML</code> <code class="inline-code">output_format</code>,
and those whose name ends with <code class="inline-code">&quot;.ftlx&quot;</code>
get <code class="inline-code">XML</code> <code class="inline-code">output_format</code>,
in both cases with auto-escaping on. If <a href="pgui_config_incompatible_improvements.html#pgui_config_incompatible_improvements_how_to_set">the
<code>incompatible_improvements</code> setting</a>
is set to 2.3.24 (or higher) then this setting defaults to
<code class="inline-code">true</code>. Otherwise it&#39;s default is
<code class="inline-code">false</code>, but enabling it is highly
recommended.</p>
</li>
<li>
<p>Added new configuration setting:
<code class="inline-code">output_format</code>. This specifies the <a href="dgui_misc_autoescaping.html#dgui_misc_autoescaping_outputformat">output
format</a> object to use (such as
<code class="inline-code">HTMLOutputFormat.INSTANCE</code>,
<code class="inline-code">XMLOutputFormat.INSTANCE</code>, etc.) that
governs auto-escaping. The output format can be different
for different templates, using the
<code class="inline-code">template_configurations</code> setting (<a href="pgui_config_outputformatsautoesc.html">see here
how...</a>).</p>
</li>
<li>
<p>Added new configuration setting:
<code class="inline-code">registered_custom_output_formats</code>. With
this you can add new <code class="inline-code">OutputFormat</code>-s that
templates can refer to by name (like in <code class="inline-code">&lt;#ftl
output_format=&quot;foo&quot;&gt;</code>).</p>
</li>
<li>
<p>Added new configuration setting:
<code class="inline-code">auto_escaping_policy</code>. This decides when
auto-escaping should be enabled depending on the current
output format.</p>
</li>
</ul>
</li>
<li>
<p>Changes related to the custom number and
date/time/datetime formating feature:</p>
<ul>
<li>
<p>Added new classes for implementing custom formatters:
<code class="inline-code">freemarker.core.TemplateNumberFormat</code>,
<code class="inline-code">TemplateNumberFormatFactory</code>,
<code class="inline-code">TemplateDateFormat</code>,
<code class="inline-code">TemplateDateFormatFactory</code>, also the
exceptions these can throw. These allow implementing any
kind of formatting rule that&#39;s doable in Java (i.e., they
aren&#39;t restricted to any <code class="inline-code">java.text</code>
formatters). Furthermore these formatters get the
<code class="inline-code">TemplateModel</code> instead of a the bare
<code class="inline-code">java.lang.Number</code> or
<code class="inline-code">java.util.Date</code>, which lets you use the
extra application-specific meta information that you may
pack into the <code class="inline-code">TemplateModel</code>-s, such as
physical unit, preferred precision, and so on.</p>
</li>
<li>
<p>Added <code class="inline-code">custom_number_formats</code> and
<code class="inline-code">custom_date_formats</code> settings
(<code class="inline-code">Configurable.setCustomNumberFormats(Map&lt;String,
TemplateNumberFormatFactory&gt;)</code> and
<code class="inline-code">Configurable.setCustomDateFormats(Map&lt;String,
TemplateDateFormatFactory&gt;)</code>) with which you can
register your own formats. These formats can be referred
from everywhere where you can use a string to define a
format, with a format string like <code class="inline-code">&quot;@foo&quot;</code>
or <code class="inline-code">&quot;@foo params&quot;</code>, where
<code class="inline-code">&quot;foo&quot;</code> is the key in the
<code class="inline-code">Map&lt;String, ...&gt;</code> parameter of the
earlier shown methods, and the parameters (if any) are
interpreted by the
<code class="inline-code">Template<em class="code-color">Xxx</em>FormatFactory</code>
implementation that you provide. Like, you can issue
<code class="inline-code">cfg.setNumberFormat(&quot;@foo params&quot;)</code>, or
<code class="inline-code">&lt;#setting number_format=&#39;@foo
params&#39;&gt;</code>, or
<code class="inline-code">${n?string.@foo_params}</code>, similarly as you
can issue <code class="inline-code">cfg.setNumberFormat(&quot;0.##&quot;)</code>,
etc. For backward compatibility, the initial
<code class="inline-code">@</code> only has this special meaning if either
you have any custom formats or <a href="pgui_config_incompatible_improvements.html">the
<code>incompatible_improvements</code> setting</a>
is at least 2.3.24. Note that the
<code class="inline-code">custom_number_formats</code> and
<code class="inline-code">custom_date_formats</code> settings can be set
per-template (via the new
<code class="inline-code">template_configurations</code> settings) or
per-<code class="inline-code">Environment</code> too, thus
<code class="inline-code">@foo</code> can mean something different in
different templates.</p>
</li>
<li>
<p>Added new <code class="inline-code">Environment</code> methods
returning <code class="inline-code">TemplateNumberFormat</code> and
<code class="inline-code">TemplateDateFormat</code> objects. See the
<code class="inline-code">getTemplateNumberFormat(<em class="code-color">...</em>)</code>
and
<code class="inline-code">getTemplateDateFormat(<em class="code-color">...</em>)</code>
variations in the API.</p>
</li>
<li>
<p>Added
<code class="inline-code">freemarker.core.AliasTemplateNumberFormatFactory</code>
and <code class="inline-code">AliasTemplateDateFormatFactory</code>, which
can be used to create custom formats that are aliases to
other formats. For example, instead of writing
<code class="inline-code">${n?string[&quot;0.00&quot;]}</code> again and again, you
can define the custom format <code class="inline-code">&quot;price&quot;</code> as
the alias to the format string <code class="inline-code">&quot;0.00&quot;</code> in
the configuration, and then use
<code class="inline-code">${n?string.@price}</code>. Thus, you can control
at a central place how prices look. Furthermore, the alias
can chose a different target format string depending on the
current locale; this is especially useful for dates, where
conventions can significantly differ in different
countries.</p>
</li>
<li>
<p>It&#39;s now possible to have HTML or other markup in
number and date/time/datetime formatting results, like
<code class="inline-code">1.23*10&lt;sup&gt;6&lt;/sup&gt;</code>, which
won&#39;t be accidentally auto-escaped, as FreeMarker knows that
it&#39;s already HTML. This is done by returning a
<code class="inline-code">TemplateMarkupOutputModel</code> instead of a
<code class="inline-code">String</code>; see the new auto-escaping
mechanism earlier. Note that no out-of-the-box format
utilizes this (at the moment), but you could write such
custom format.</p>
</li>
<li>
<p>The internal format object caching architecture has
been reworked, so that it can handle custom formats too.
This reworking also fixes some bottlenecks under highly
concurrent load, and some (otherwise unlikely) memory leak
possibilities.</p>
</li>
</ul>
</li>
<li>
<p>In the <code class="inline-code">number_format</code> configuration
setting, when it holds a Java <code class="inline-code">DecimalFormat</code>
pattern (like <code class="inline-code">&quot;0.##&quot;</code>), it&#39;s now possible to
specify options like rounding mode or the symbols used, with a
FreeMarker-specific <a href="ref_builtins_number.html#topic.extendedJavaDecimalFormat">extension to the
pattern syntax</a>.</p>
</li>
<li>
<p>New <code class="inline-code">FreemarkerServlet</code> init-params (see
<a href="https://freemarker.apache.org/docs/api/freemarker/ext/servlet/FreemarkerServlet.html">the
<code>FreemarkerSerlvet</code> API documentation</a>
for details):</p>
<ul>
<li>
<p><code class="inline-code">OverrideResponseContentType</code>:
Specifies when should we override the
<code class="inline-code">contentType</code> that&#39;s already set (i.e.,
non-<code class="inline-code">null</code>) in the
<code class="inline-code">HttpServletResponse</code>. Earlier, we have
always set it, and that&#39;s still the default behavior. But
now that this init-param exists, you can change that
behavior, so that the <code class="inline-code">contentType</code> you
have specified before forwarding to
<code class="inline-code">FreemarkerServlet</code> matters.</p>
</li>
<li>
<p><code class="inline-code">OverrideResponseLocale</code>: Specifies
if we should override the <code class="inline-code">locale</code> that&#39;s
already set (i.e., non-<code class="inline-code">null</code>) in the
<code class="inline-code">HttpServletResponse</code>. Earlier, we have
always set it, but now this behavior can be changed so that
we only set it if it wasn&#39;t already set.</p>
</li>
<li>
<p><code class="inline-code">ResponseCharacterEncoding</code>:
Deprecates the old (and quirky) logic of specifying the
output charset, which is putting it into the
<code class="inline-code">ContentType</code> init-param after the MIME
type, otherwise falling back to the template file charset.
The possible values are <code class="inline-code">legacy</code> (the
default for backward compatibility),
<code class="inline-code">fromTemplate</code> (which is
<code class="inline-code">legacy</code> without quirks, and is aware of
the <code class="inline-code">outputEncoding</code> setting),
<code class="inline-code">doNotSet</code> (keeps what the caller has
already set in the <code class="inline-code">ServletRespone</code>) and
<code class="inline-code">force</code> followed by a charset name (forces
a specific output charset).</p>
</li>
</ul>
</li>
<li>
<p>Added
<code class="inline-code">freemarker.cache.ByteArrayTemplateLoader</code>,
which is similar to <code class="inline-code">StringTemplateLoader</code>, but
stores the templates as <code class="inline-code">byte[]</code>-s instead of
as <code class="inline-code">String</code>-s.</p>
</li>
<li>
<p>Upgraded JavaCC (used during build to generate the FTL
parser) from 3.2 to 6.1.2.</p>
</li>
<li>
<p>Added <code class="inline-code">Configurable.getSettingNames(boolean
camelCase)</code>, which returns the set of valid setting
names. This can be useful for auto-completion and such.</p>
</li>
<li>
<p>Fixes and improvements in the "object
builder" mini-language used for configuring FreeMarker
from <code class="inline-code">java.util.Properties</code> or other
string-only sources (not used in templates). This is
<em>not to be confused with the template language
syntax</em>, which has nothing to do with the
"object builder" syntax we are writing about here.
The improvements are:</p>
<ul>
<li>
<p>Bug fixed: For nested builder expressions, the
top-level result class restriction were applied
accidentally.</p>
</li>
<li>
<p>When resolving an expression like
<code class="inline-code">com.example.Foo()</code>, if there&#39;s a builder
class (<code class="inline-code">com.example.FooBuilder</code>), the
non-builder class (<code class="inline-code">com.example.Foo</code>) need
not exist anymore. After all,
<code class="inline-code">FooBuilder.build()</code> instantiates from any
class it wants to anyway.</p>
</li>
<li>
<p><code class="inline-code">TimeZone</code> objects can be created
like <code class="inline-code">TimeZone(&quot;UTC&quot;)</code>, despite that
there&#39;s no a such constructor.</p>
</li>
<li>
<p>Added support for creating lists with <code class="inline-code">[
<em class="code-color">item1</em>,
<em class="code-color">item2</em>,
<em class="code-color">...</em>
<em class="code-color">itemN</em> ]</code> syntax.</p>
</li>
<li>
<p>Added support for creating maps with <code class="inline-code">{
<em class="code-color">key1</em>:
<em class="code-color">value1</em>,
<em class="code-color">key2</em>:
<em class="code-color">value2</em>,
<em class="code-color">...</em>
<em class="code-color">keyN</em>:
<em class="code-color">valueN</em> }</code> syntax.</p>
</li>
<li>
<p>A number without decimal point will now be parsed to
<code class="inline-code">Integer</code>, <code class="inline-code">Long</code>, or
<code class="inline-code">BigInteger</code>, depending on the size of the
number. Earlier all numbers were parsed to
<code class="inline-code">BigDecimal</code>-s, but that had little
importance before lists and maps were added, as the number
was converted to the constructor or setter parameter type
anyway.</p>
</li>
<li>
<p>Number literals can have Java type suffixes
(<code class="inline-code">f</code>, <code class="inline-code">d</code>,
<code class="inline-code">l</code>), plus <code class="inline-code">bd</code> for
<code class="inline-code">BigDecimal</code> and <code class="inline-code">bi</code> for
<code class="inline-code">BigInteger</code>.</p>
</li>
<li>
<p>Public static fields can be referred, like
<code class="inline-code">com.example.MyClass.MY_CONSTANT</code> or
<code class="inline-code">Configuration.AUTO_DETECT_TAG_SYNTAX</code>.</p>
</li>
</ul>
</li>
<li>
<p>Decreased the stack usage of template execution, which can
have importance if you have very very deeply nested
templates.</p>
</li>
<li>
<p>Added
<code class="inline-code">MultiTemplateLoader.setSticky(boolean)</code> and
<code class="inline-code">MultiTemplateLoader.isSticky()</code>, with which
you can disable the default behavior, where once a template was
found in a child <code class="inline-code">TemplateLoader</code>, it will be
searched there first next time (typically, when the template
update delay is expired). With the <code class="inline-code">sticky</code>
property set to <code class="inline-code">false</code>, the child
<code class="inline-code">TemplateLoader</code>-s will be always searched in
the order as they were added to the
<code class="inline-code">MultiTemplateLoader</code>.</p>
</li>
<li>
<p>Added
<code class="inline-code">StringTemplateLoader.removeTemplate(String)</code>
method.</p>
</li>
<li>
<p>Bug fixed, only with
<code class="inline-code">incompatible_improvements</code> set to 2.3.24
(<a href="pgui_datamodel_objectWrapper.html#topic.defaultObjectWrapperIcI">see how
here...</a>): Expressions inside interpolations that were
inside <em>string literal expressions</em> (not
<code class="inline-code">${<em class="code-color">...</em>}</code>-s in
general), like in <code class="inline-code">&lt;#assign s=&quot;Hello
${name}!&quot;&gt;</code>, always used
<code class="inline-code">incompatibleImprovements</code> 0 (2.3.0 in effect).
This means that expressions inside string literals had missed
the <code class="inline-code">?html</code>,
<code class="inline-code">?iso_<em class="code-color">...</em></code>,
<code class="inline-code">?is_enumerable</code>, <code class="inline-code">?c</code>, etc.
fixes/improvements.</p>
</li>
<li>
<p>Bug fixed [<a href="https://sourceforge.net/p/freemarker/bugs/439/">439</a>]:
<code class="inline-code">FileTemplateLoader</code> with
<code class="inline-code">emulateCaseSensitiveFileSystem</code> set to
<code class="inline-code">true</code> (used for development) wasn&#39;t properly
synchronized, leading to random
<code class="inline-code">NullPointerException</code>-s or other
misbehavior.</p>
</li>
<li>
<p>Bug fixed: It wasn&#39;t well defined when a Java
<code class="inline-code">Iterator</code> counts as empty. Depending on what
<code class="inline-code">ObjectWrapper</code> you are using, one of these
fixes apply:</p>
<ul>
<li>
<p><code class="inline-code">DefaultObjectWrapper</code> (fix is always
active): Operations on the <code class="inline-code">Iterator</code> that
only check if it&#39;s empty without reading an element from it,
such as <code class="inline-code">?has_content</code>, won&#39;t cause a later
iteration (or further emptiness check) to fail anymore.
Earlier, in certain situations, the second operation has
failed saying that the iterator "can be listed only
once".</p>
</li>
<li>
<p><code class="inline-code">BeansWrapper</code> (when it&#39;s not
extended by <code class="inline-code">DefaultObjectWrapper</code>), if
it&#39;s <code class="inline-code">incompatibleImprovements</code> property is
set to 2.3.24 (or higher): <code class="inline-code">Iterator</code>-s
were always said to be non-empty when using
<code class="inline-code">?has_content</code> and such (i.e., operators
that check emptiness without reading any elements). Now an
<code class="inline-code">Iterator</code> counts as empty exactly if it
has no elements left. (Note that this bug has never affected
basic functionality, like <code class="inline-code">&lt;#list
...&gt;</code>.)</p>
</li>
</ul>
</li>
<li>
<p>Bug fixed: The (rarely used) cause exception of
<code class="inline-code">ParseException</code>-s wasn&#39;t set</p>
</li>
<li>
<p>Bug fixed: When the
<code class="inline-code">incomaptible_improvements</code> setting of an
existing <code class="inline-code">Configuration</code> was changed, the
template cache sometimes wasn&#39;t recreated, hence old templates
could survive.</p>
</li>
<li>
<p>Bug fixed, with
<code class="inline-code">incompatible_improvements</code> set to 2.3.24
(<a href="pgui_datamodel_objectWrapper.html#topic.defaultObjectWrapperIcI">see how
here...</a>): The <code class="inline-code">#import</code> directive meant
to copy the library variable into a global variable if it&#39;s
executed in the main namespace, but that haven&#39;t happened when
the imported template was already imported earlier in another
namespace.</p>
</li>
<li>
<p>Fixes in the XML processing feature
(<code class="inline-code">freemarker.ext.dom</code>):</p>
<ul>
<li>
<p>Bug fixed: XPath queries that has only contained
characters that are valid in XML element names and has also
contained <code class="inline-code">::</code> (which is valid in names in
namespace-unware documents), like
<code class="inline-code">e[&#39;following-sibling::foo&#39;]</code>, were
interpreted as literal element names (giving 0 hits) rather
than as XPath expressions. Note that there were no such
problem with <code class="inline-code">e[&#39;following-sibling::*&#39;]</code>
for example, as it&#39;s not a valid XML element name according
the XML specification. This fix can actually break
applications that has processed namespace unaware XML that
use <code class="inline-code">::</code> as part of element or attribute
names, but such an application is highly unlikely, unlike
running into the fixed problem. (Unfortunately, using
<code class="inline-code">incompatible_improvements</code> wasn&#39;t
technically possible here.)</p>
</li>
<li>
<p>Bug fixed: The <code class="inline-code">@@qname</code> of elements
that belong to the XML namespace declared as the default via
<code class="inline-code">&lt;#ftl ns_prefixes={&#39;D&#39;:&#39;...&#39;, ...
}&gt;</code> no longer starts with <code class="inline-code">D:</code>,
instead they just start with no name space prefix.</p>
</li>
<li>
<p>Bug fixed: In the markup returned by the
<code class="inline-code">@@markup</code> key, when there were multiple
namespaces for which there was no prefix associated with via
<code class="inline-code">&lt;#ftl
ns_prefixes=<em class="code-color">...</em>&gt;</code>,
all those namespaces were assigned to the same
auto-generated <code class="inline-code">xmlns</code> prefix (usually
"a"). Now they will get "a",
"b", "c", etc. prefixes.</p>
</li>
</ul>
</li>
<li>
<p>JSP TLD loading now quotes the location of
<code class="inline-code">jar</code>-s (and other <code class="inline-code">zip</code>-s)
which can&#39;t be loaded due to zip format errors in the error
message.</p>
</li>
<li>
<p>Added an overload to
<code class="inline-code">Configuration.getSupportedBuiltInNames</code> and
<code class="inline-code">Configuration.getSupportedBuiltInDirectiveNames</code>
that has a <code class="inline-code">namingConvention</code> parameter. This
is useful for tooling as since 2.3.23 we support both camel case
naming convention (like
<code class="inline-code"><em class="code-color">s</em>?upperCase</code>) and
the legacy one (like
<code class="inline-code"><em class="code-color">s</em>?upper_case</code>).
Furthermore the old 0 argument overload will now utilize
<code class="inline-code">Configuration.getNamingConvention()</code> to only
return the relevant names if it&#39;s not
<code class="inline-code">AUTO_DETECT_NAMING_CONVENTION</code>.</p>
</li>
<li>
<p>Internal reworking to simplify the AST (the
<code class="inline-code">TemplateElement</code> structure). The related
technically public API was marked as internal for a good while.
For those who still use that API, the visible change is that
<code class="inline-code">TemplateElement</code>-s now almost never has a
<code class="inline-code">MixedContent</code> parent, instead, the parent is
directly whatever element the child element indeed belongs under
when you look at the source code (like the enclosing
<code class="inline-code">#list</code> for example, while earlier you often
had to go through a <code class="inline-code">MixedContent</code> first whose
parent was the <code class="inline-code">#list</code>). Note that when you
have moved downwards, i.e., towards the child elements, these
<code class="inline-code">MixedContent</code> parents weren&#39;t visible and were
silently skipped, so the tree traversal API was inconsistent.
Now it&#39;s consistent.</p>
</li>
<li>
<p>Due to the above change again, the return type of
<code class="inline-code">freemarker.core.DebugBreak.accept()</code> and
<code class="inline-code">freemarker.core.TextBlock.accept()</code> has
changed from <code class="inline-code">void</code> to
<code class="inline-code">TemplateElement[]</code>. This again is highly
unlikely to affect anyone, and these meant to be internal API-s
anyway, but as these two <code class="inline-code">accept</code> methods has
wider than package visibility for historical reasons, we mention
this change.</p>
</li>
<li>
<p>The non-public AST API of
<code class="inline-code">freemarker.core.StringLiteral</code>-s has been
changed. In principle it doesn&#39;t mater as it isn&#39;t a public API,
but some might used these regardless to introspect templates.
Earlier it had an "embedded template" parameter
inside, now it has 0 (for purely static string literals), one or
more "value part"-s, which are
<code class="inline-code">String</code>-s and
<code class="inline-code">Interpolation</code>-s.</p>
</li>
<li>
<p>Internal code cleanup: Mostly for consistent source code
formatting, also many parser construction/setup cleanup</p>
</li>
<li>
<p>Source code changes to conform to Apache source release
policy, such as adding copyright headers and getting rid of test
<code class="inline-code">jar</code>-s committed into the source code. Eclipse
project files were also removed, instead the
<code class="inline-code">README</code> describes how to set up the
project.</p>
</li>
<li>
<p>Build script and distribution artifact changes to conform
to Apache release policy, most notably it produces separate
source and binary releases.</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_171">Changes compared to 2.3.24 Release Candidate 1</h2>
<ul>
<li>
<p>Added
<code class="inline-code">MultiTemplateLoader.setSticky(boolean)</code> and
<code class="inline-code">MultiTemplateLoader.isSticky()</code>, with which
you can disable the default behavior, where once a template was
found in a child <code class="inline-code">TemplateLoader</code>, it will be
searched there first next time (typically, when the template
update delay is expired). With the <code class="inline-code">sticky</code>
property set to <code class="inline-code">false</code>, the child
<code class="inline-code">TemplateLoader</code>-s will be always searched in
the order as they were added to the
<code class="inline-code">MultiTemplateLoader</code>.</p>
</li>
<li>
<p>Added
<code class="inline-code">StringTemplateLoader.removeTemplate(String)</code>
method.</p>
</li>
<li>
<p>Source code changes to conform to Apache release policy
and recommendations:</p>
<ul>
<li>
<p>No more binary test <code class="inline-code">jar</code>-s committed
into the source code (instead, they are generated
on-the-fly)</p>
</li>
<li>
<p>Eclipse project files were removed, instead, the
<code class="inline-code">README</code> describes how to set up the
project.</p>
</li>
</ul>
</li>
</ul>
<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="versions_2_3_25.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3_23.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>