blob: 9f0b1a3bcb233e96d5e46b2199fb7064d81a6de2 [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 - 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">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="https://freemarker.apache.org/docs/versions_2_3.html">
<link rel="canonical" href="https://freemarker.apache.org/docs/versions_2_3.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.html"><span itemprop="name">2.3</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"];</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_1.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_2_8.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="versions_2_3" itemprop="headline">2.3</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#autoid_228" data-menu-target="autoid_228">Non backward-compatible changes!</a></li><li><a class="page-menu-link" href="#autoid_229" data-menu-target="autoid_229">Changes on the FTL side</a></li><li><a class="page-menu-link" href="#autoid_230" data-menu-target="autoid_230">Changes on the Java side</a></li><li><a class="page-menu-link" href="#autoid_231" data-menu-target="autoid_231">Other changes</a></li><li><a class="page-menu-link" href="#autoid_232" data-menu-target="autoid_232">The history of the releases before the final version</a><ul><li><a class="page-menu-link" href="#autoid_233" data-menu-target="autoid_233">Differences between the final release and Release Candidate
4</a></li><li><a class="page-menu-link" href="#autoid_234" data-menu-target="autoid_234">Differences between the Release Candidate 4 and Release
Candidate 3</a></li><li><a class="page-menu-link" href="#autoid_235" data-menu-target="autoid_235">Differences between the Release Candidate 3 and Release
Candidate 2</a></li><li><a class="page-menu-link" href="#autoid_236" data-menu-target="autoid_236">Differences between the Release Candidate 2 and Release
Candidate 1</a></li><li><a class="page-menu-link" href="#autoid_237" data-menu-target="autoid_237">Differences between the Release Candidate 1 and Preview 16
releases</a></li><li><a class="page-menu-link" href="#autoid_238" data-menu-target="autoid_238">Differences between the Preview 16 and Preview 15
releases</a></li><li><a class="page-menu-link" href="#autoid_239" data-menu-target="autoid_239">Differences between the Preview 15 and Preview 14
releases</a></li><li><a class="page-menu-link" href="#autoid_240" data-menu-target="autoid_240">Differences between the Preview 14 and Preview 13
releases</a></li><li><a class="page-menu-link" href="#autoid_241" data-menu-target="autoid_241">Differences between the Preview 13 and Preview 12
releases</a></li><li><a class="page-menu-link" href="#autoid_242" data-menu-target="autoid_242">Differences between the Preview 12 and Preview 11
releases</a></li><li><a class="page-menu-link" href="#autoid_243" data-menu-target="autoid_243">Differences between the Preview 11 and Preview 10
releases</a></li><li><a class="page-menu-link" href="#autoid_244" data-menu-target="autoid_244">Differences between the Preview 10 and Preview 9
releases</a></li><li><a class="page-menu-link" href="#autoid_245" data-menu-target="autoid_245">Differences between the Preview 9 and Preview 8
releases</a></li><li><a class="page-menu-link" href="#autoid_246" data-menu-target="autoid_246">Differences between the Preview 8 and Preview 7
releases</a></li><li><a class="page-menu-link" href="#autoid_247" data-menu-target="autoid_247">Differences between the Preview 7 and Preview 6
releases</a></li><li><a class="page-menu-link" href="#autoid_248" data-menu-target="autoid_248">Differences between the Preview 6 and Preview 5
releases</a></li><li><a class="page-menu-link" href="#autoid_249" data-menu-target="autoid_249">Differences between the Preview 5 and Preview 4
releases</a></li><li><a class="page-menu-link" href="#autoid_250" data-menu-target="autoid_250">Differences between the Preview 4 and Preview 3
releases</a></li><li><a class="page-menu-link" href="#autoid_251" data-menu-target="autoid_251">Differences between the Preview 3 and Preview 2
releases</a></li><li><a class="page-menu-link" href="#autoid_252" data-menu-target="autoid_252">Differences between the Preview 2 and Preview 1
releases</a></li></ul></li></ul> </div><p>Date of release: 2004-June-15</p><p>FreeMarker 2.3 introduces numerous little new features and
quality improvements compared to the 2.2.x series. The most notable
improvements are the ability to define functions (methods) in
templates, the ability to interpolate variables in string literals,
the support for a variable number of macro parameters, and the more
intelligent default object wrapper. Although none of the improvements
is a drastic change, the 2.3.x series is not backward compatible with
the 2.2.x series (see the list below), so you may choose to use it for
new projects only.</p><p>Probably the most "loudly promoted" new feature is
the totally redesigned XML wrapper. With the new XML wrapper
FreeMarker targets a new application domain, which is similar to the
application domain of XSLT: transforming complex XML to whatever
textual output. Although this subproject is young, it is definitely
usable in practice. See the <a href="xgui.html">XML Processing
Guide</a> for more details.</p>
<h2 class="content-header header-section2" id="autoid_228">Non backward-compatible changes!</h2>
<ul>
<li>
<p>Since interpolations (<code class="inline-code">${...}</code> and
<code class="inline-code">#{...}</code>) now work inside string literals, the
character sequence <code class="inline-code">${</code> and
<code class="inline-code">#{</code> in string literals are reserved for that.
So if you have something like <code class="inline-code">&lt;#set x =
&quot;${foo}&quot;&gt;</code>, then you have to replace it with
<code class="inline-code">&lt;#set x = r&quot;${foo}&quot;&gt;</code> -- beware, escapes
such as <code class="inline-code">\n</code> will not work in raw
(<code class="inline-code">r</code>) strings.</p>
</li>
<li>
<p>The default (initial) value of the
<code class="inline-code">strict_syntax</code> setting has been changed from
<code class="inline-code">false</code> to <code class="inline-code">true</code>. When
<code class="inline-code">strict_syntax</code> is <code class="inline-code">true</code>,
tags with old syntax as <code class="inline-code">&lt;include
&quot;foo.ftl&quot;&gt;</code> will be considered as static text (so
they go to the output as-is, like HTML tags do), and not as FTL
tags. Such tags have to be rewritten to <code class="inline-code">&lt;#include
&quot;foo.ftl&quot;&gt;</code>, since only parts that starts with
<code class="inline-code">&lt;#</code>, <code class="inline-code">&lt;/#</code>,
<code class="inline-code">&lt;@</code>, or <code class="inline-code">&lt;/@</code> count as
FTL tags. Or, to recover the old transitional behavior, where
both legacy and new tag syntax was recognized, you have to
explicitly set <code class="inline-code">strict_syntax</code> to
<code class="inline-code">false</code>:
<code class="inline-code">cfg.setStrictSyntaxMode(false)</code>. Also, for
individual templates you can force the old behavior by starting
the template with <code class="inline-code">&lt;#ftl
strict_syntax=false&gt;</code>. (For more information about
why strict syntax is better than old syntax <a href="ref_depr_oldsyntax.html">read this...</a>)</p>
</li>
<li>
<p>Several classes were moved from the
<code class="inline-code">freemarker.template</code> package, to the new
<code class="inline-code">freemarker.core</code> package:</p>
<ul>
<li>
&quot;Normal&quot; classes: <code class="inline-code">ArithmeticEngine</code>,
<code class="inline-code">Configurable</code>,
<em><code class="inline-code">Environment</code></em>
</li>
<li>
Exceptions:
<code class="inline-code">InvalidReferenceException</code>,
<code class="inline-code">NonBooleanException</code>,
<code class="inline-code">NonNumericalException</code>,
<code class="inline-code">NonStringException</code>,
<code class="inline-code">ParseException</code>,
<code class="inline-code">StopException</code>
</li>
<li>
Errors: <code class="inline-code">TokenMgrError</code>
</li>
</ul>
<p>The main reason of the splitting of
<code class="inline-code">freemarker.template</code> package was that the
amount of &quot;expert&quot; public classes and interfaces grows too much,
as we introduce API-s for third-party tools, such as debugging
API.</p>
</li>
<li>
<p><code class="inline-code">freemarker.template.TemplateMethodModel.exec</code>
now returns <code class="inline-code">Object</code> instead of
<code class="inline-code">TemplateModel</code>.</p>
</li>
<li>
<p>White-space stripping is now more aggressive as before: it
always removes leading and trailing white-space if the line only
contains FTL tags. (Earlier the white-space was not removed if
the tag was <code class="inline-code">&lt;#include
<em class="code-color">...</em>&gt;</code> or user-defined
directive tag with empty directive syntax as
<code class="inline-code">&lt;@myMacro/&gt;</code> (or its equivalents:
<code class="inline-code">&lt;@myMacro&gt;&lt;/@myMacro&gt;</code> and
<code class="inline-code">&lt;@myMacro&gt;&lt;/@&gt;</code>). Now white-space
is removed in these cases as well.) Also, white-space sandwiched
between two non-outputting elements, such as macro definitions,
assignments, imports, or property settings, is now ignored. More
information: <a href="dgui_misc_whitespace.html#dgui_misc_whitespace_stripping">Template Author&#39;s Guide/Miscellaneous/White-space handling/White-space stripping</a></p>
</li>
<li>
<p>The <code class="inline-code">function</code> directive is now used for
defining methods. You should replace <code class="inline-code">function</code>
with <code class="inline-code">macro</code> in your old templates. Note,
however, that old <code class="inline-code">function</code>-s will still work
if you don&#39;t use the <code class="inline-code">return</code> directive in
them, and you invoke them with the deprecated the
<code class="inline-code">call</code> directive.</p>
</li>
<li>
<p>The expressions <code class="inline-code">as</code>,
<code class="inline-code">in</code>, and <code class="inline-code">using</code> are now
keywords in the template language and cannot be used as
top-level variable names without square-bracket syntax. If, by
some chance, you have top-level variables that use one of these
names, you will have to rename them, or use the square-bracket
syntax with the <code class="inline-code">.vars</code> special variable:
<code class="inline-code">.vars[&quot;in&quot;]</code>.</p>
</li>
<li>
<p>The <code class="inline-code">?new</code> built-in, as it was
implemented, was a security hole. Now, it only allows you to
instantiate a java object that implements the
<code class="inline-code">freemarker.template.TemplateModel</code> interface.
If you want the functionality of the <code class="inline-code">?new</code>
built-in as it existed in prior versions, make available an
instance of the
<code class="inline-code">freemarker.template.utility.ObjectConstructor</code>
class to your template. (For example:
<code class="inline-code">myDataModel.put(&quot;objConstructor&quot;, new
ObjectConstructor());</code>, and then in the template you
can do this: <code class="inline-code">&lt;#assign aList =
objConstructor(&quot;java.util.ArrayList&quot;, 100)&gt;</code>)</p>
</li>
<li>
<p>Changes to the
<code class="inline-code">FreemarkerServlet</code>:</p>
<ul>
<li>
<p>The <code class="inline-code">FreemarkerServlet</code> uses
<code class="inline-code">ObjectWrapper.DEFAULT_WRAPPER</code> by default
instead of <code class="inline-code">ObjectWrapper.BEANS_WRAPPER</code>.
What this means is that, by default, objects of type
<code class="inline-code">java.lang.String</code>,
<code class="inline-code">java.lang.Number</code>,
<code class="inline-code">java.util.List</code>, and
<code class="inline-code">java.util.Map</code> will be wrapped as
<code class="inline-code">TemplateModels</code> via the classes
<code class="inline-code">SimpleScalar</code>,
<code class="inline-code">SimpleNumber</code>,
<code class="inline-code">SimpleSequence</code>, and
<code class="inline-code">SimpleHash</code> respectively. Thus, the java
methods on those objects will not be available. The default
wrapper implementation in FreeMarker 2.3 automatically knows
how to wrap Jython objects, and also wraps
<code class="inline-code">org.w3c.dom.Node</code> objects into instances
of <code class="inline-code">freemarker.ext.dom.NodeModel</code>.</p>
</li>
<li>
<p>The <code class="inline-code">FreemarkerServlet</code> base
implementation no longer deduces the locale used for
templates with <code class="inline-code">HttpRequest.getLocale()</code>.
Rather, it simply delegates to the new protected method,
<code class="inline-code">deduceLocale</code>. The default implementation
of this method simply returns the value of configuration the
<code class="inline-code">locale</code> setting.</p>
</li>
</ul>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_229">Changes on the FTL side</h2>
<ul>
<li>
<p>Interpolation in string literals. For convenience,
interpolations are now supported in string literals. For
example: <code class="inline-code">&lt;@message &quot;Hello ${user}!&quot; /&gt;</code>
is the same as <code class="inline-code">&lt;@message &quot;Hello &quot; + user + &quot;!&quot;
/&gt;</code></p>
</li>
<li>
<p>Raw string literals: In string literals prefixed with
<code class="inline-code">r</code>, interpolations and escape sequences will
not be interpreted as special tokens. For example:
<code class="inline-code">r&quot;\n${x}&quot;</code> will be simply interpreted as the
character sequence <code class="inline-code">&#39;\&#39;</code>,
<code class="inline-code">&#39;n&#39;</code>, <code class="inline-code">&#39;$&#39;</code>,
<code class="inline-code">&#39;{&#39;</code>, <code class="inline-code">&#39;x&#39;</code>,
<code class="inline-code">&#39;}&#39;</code>, and not as line-feed and the value of
the <code class="inline-code">x</code> variable.</p>
</li>
<li>
<p>Method variables can be defined in FTL, with the <a href="ref_directive_function.html#ref.directive.function"><code>function</code></a>
directive.</p>
</li>
<li>
<p>Support for a variable number of macro parameters. If the
last parameter in a macro declaration ends with
<code class="inline-code">...</code>, all extra parameters passed to the macro
will be available via that parameter. For macros called with
positional parameters, the parameter will be a sequence. For
named parameters, the parameter will be a hash. Note that it all
works with the new <code class="inline-code">function</code> directive as
well.</p>
</li>
<li>
<p>A new header parameter, <code class="inline-code">strip_text</code>,
that removes all top-level text from a template. This is useful
for "include files" to suppress newlines that
separate the macro definitions. See <a href="ref_directive_ftl.html#ref.directive.ftl"><code>ftl</code>
directive</a></p>
</li>
<li>
<p>New <a href="ref_specvar.html">special variable</a>:
<code class="inline-code">.vars</code>. This is useful to read top-level
variables with square bracket syntax, for example
<code class="inline-code">.vars[&quot;name-with-hyphens&quot;]</code> and
<code class="inline-code">.vars[dynamicName]</code>.</p>
</li>
<li>
<p><code class="inline-code">macro</code> and assignment directives now
accept arbitrary destination variable name with quoted syntax.
For example: <code class="inline-code">&lt;#macro
&quot;name-with-hyphens&quot;&gt;<em class="code-color">...</em></code>
or <code class="inline-code">&lt;#assign &quot;foo bar&quot; = 123&gt;</code>.</p>
</li>
<li>
<p>The <code class="inline-code">?keys</code> and
<code class="inline-code">?values</code> hash built-ins now return sequences.
In practical terms this means you can access their sizes or
retrieve their sub variables by index, and use all of the <a href="ref_builtins_sequence.html">sequence built-ins</a>. (Note
for the programmers: The <code class="inline-code">TemplateHashModelEx</code>
interface has not been changed. Your old code will work. See the
API documentation to see why.)</p>
</li>
<li>
<p>Existence built-ins (<code class="inline-code">?default</code>,
<code class="inline-code">?exists</code>, etc.) are now working with sequence
sub variables as well. Read the documentation of the
<code class="inline-code">default</code> built-in for more information.</p>
</li>
<li>
<p>White-space stripping is now more aggressive as before: it
always removes leading and trailing white-space if the line only
contains FTL tags. (Earlier the white-space was not removed if
the tag was <code class="inline-code">&lt;#include
<em class="code-color">...</em>&gt;</code> or user-defined
directive tag with empty directive syntax as
<code class="inline-code">&lt;@myMacro/&gt;</code> (or its equivalents:
<code class="inline-code">&lt;@myMacro&gt;&lt;/@myMacro&gt;</code> and
<code class="inline-code">&lt;@myMacro&gt;&lt;/@&gt;</code>). Now white-space
is removed in these cases as well.) Also, top-level white-space
that separates macro definitions and/or assignments is now
ignored. More information: <a href="dgui_misc_whitespace.html#dgui_misc_whitespace_stripping">Template Author&#39;s Guide/Miscellaneous/White-space handling/White-space stripping</a></p>
</li>
<li>
<p>White-space stripping can be disabled for a single line
with the <a href="ref_directive_nt.html#ref.directive.nt"><code>nt</code></a>
directive (for No Trim).</p>
</li>
<li>
<p>Hashes can be concatenated using the <code class="inline-code">+</code>
operator. The keys in the hash on the right-hand side take
precedence.</p>
</li>
<li>
<p>New built-ins for Java and JavaScript string escaping:
<a href="ref_builtins_string.html#ref_builtin_j_string">j_string</a> and <a href="ref_builtins_string.html#ref_builtin_js_string">js_string</a></p>
</li>
<li>
<p>The <code class="inline-code">replace</code> and
<code class="inline-code">split</code> built-ins now support case-insensitive
comparsion and regular expressions (J2SE 1.4+ only), and some
other new options. More information can be found <a href="ref_builtins_string.html#ref_builtin_string_flags">here</a>.</p>
</li>
<li>
<p>New built-in for regular expression matching (J2SE 1.4+
only): <a href="ref_builtins_string.html#ref_builtin_matches"><code>matches</code></a></p>
</li>
<li>
<p>New built-in, <code class="inline-code">eval</code>, to evaluate a
string as FTL expression. For example
<code class="inline-code">&quot;1+2&quot;?eval</code> returns the number 3.</p>
</li>
<li>
<p>New built-ins for Java and JavaScript string escaping:
<a href="ref_builtins_string.html#ref_builtin_j_string">j_string</a> and <a href="ref_builtins_string.html#ref_builtin_js_string">js_string</a></p>
</li>
<li>
<p>New special variables to read the value of the locale
setting: <code class="inline-code">locale</code>, <code class="inline-code">lang</code>. See
more <a href="ref_specvar.html">in the
reference...</a></p>
</li>
<li>
<p>New special variable to read the FreeMarker version
number: <code class="inline-code">version</code>. See more <a href="ref_specvar.html">in the reference...</a></p>
</li>
<li>
<p>Tree new directives, <code class="inline-code">recurse</code>,
<code class="inline-code">visit</code> and <code class="inline-code">fallback</code>, were
introduced to support declarative node-tree processing. These
are meant to be used typically (though not exclusively) for
processing XML input. Together with this, a new variable type
has been introduced, the node type. See the <a href="xgui_declarative.html">chapter on declarative XML
processing</a> for more details.</p>
</li>
<li>
<p>The <code class="inline-code">?new</code> built-in, as it was
implemented, was a security hole. Now, it only allows you to
instantiate a java object that implements the
<code class="inline-code">freemarker.template.TemplateModel</code> interface.
<span class="marked-for-programmers">If you want the functionality of
the <code class="inline-code">?new</code> built-in as it existed in prior
versions, make available an instance of the
<code class="inline-code">freemarker.template.utility.ObjectConstructor</code>
class to your template. (For example:
<code class="inline-code">myDataModel.put(&quot;objConstructor&quot;, new
ObjectConstructor());</code>, and then in the template you
can do this: <code class="inline-code">&lt;#assign aList =
objConstructor(&quot;java.util.ArrayList&quot;,
100)&gt;</code>)</span></p>
</li>
<li>
<p>Variable names can contain <code class="inline-code">@</code> anywhere
(without using quote-bracket syntax). For example:
<code class="inline-code">&lt;#assign x@@@ = 123&gt;</code> is valid.</p>
</li>
<li>
<p>The expressions <code class="inline-code">as</code>,
<code class="inline-code">in</code>, and <code class="inline-code">using</code> are now
keywords in the template language and cannot be used as
top-level variable names without square-bracket syntax (as
<code class="inline-code">.vars[&quot;in&quot;]</code>).</p>
</li>
<li>
<p>New parameter to the <a href="ref_directive_ftl.html"><code>ftl</code>
directive</a>: <code class="inline-code">attributes</code>. The value of
this attribute is a hash that associates arbitrary attributes
(name-value pairs) to the template. The values of the attributes
can be of any type (string, number, sequence... etc.).
FreeMarker doesn&#39;t try to understand the meaning of the
attributes. It&#39;s up to the application that encapsulates
FreeMarker (as a Web application framework). Thus, the set of
allowed attributes and their semantic is application (Web
application framework) dependent.</p>
</li>
<li>
<p>Other minor quality improvements...</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_230">Changes on the Java side</h2>
<ul>
<li>
<p>Smarter default object wrapping: The default object
wrapper is now
<code class="inline-code">freemarker.template.DefaultObjectWrapper</code>,
which falls back on wrapping arbitrary objects as beans using
the <code class="inline-code">freemarker.ext.beans.BeansWrapper</code>. Also,
it will wrap <code class="inline-code">org.w3c.dom.Node</code> objects with
the new DOM wrapper. Also, it is aware of Jython objects, and
will use <code class="inline-code">freemarker.ext.jython.JythonWrapper</code>
if the object passed in is a Jython object. (We count it as a
backward compatible change, since this new object wrapper wraps
differently only those objects that the old wrapper was not able
to wrap, so it has thrown exception.)</p>
</li>
<li>
<p><code class="inline-code">freemarker.template.TemplateMethodModel.exec</code>
now returns <code class="inline-code">Object</code> instead of
<code class="inline-code">TemplateModel</code>.</p>
</li>
<li>
<p>The default (initial) value of the
<code class="inline-code">strict_syntax</code> setting has been changed from
<code class="inline-code">false</code> to <code class="inline-code">true</code>. When
<code class="inline-code">strict_syntax</code> is <code class="inline-code">true</code>,
tags with old syntax as <code class="inline-code">&lt;include
&quot;foo.ftl&quot;&gt;</code> will be considered as static text (so
they go to the output as-is, like HTML tags do), and not as FTL
tags. Such tags have to be rewritten to <code class="inline-code">&lt;#include
&quot;foo.ftl&quot;&gt;</code>, since only parts that starts with
<code class="inline-code">&lt;#</code>, <code class="inline-code">&lt;/#</code>,
<code class="inline-code">&lt;@</code>, or <code class="inline-code">&lt;/@</code> count as
FTL tags. Or, to recover the old transitional behavior, where
both legacy and new tag syntax was recognized, you have to
explicitly set <code class="inline-code">strict_syntax</code> to
<code class="inline-code">false</code>:
<code class="inline-code">cfg.setStrictSyntaxMode(false)</code>. Also, for
individual templates you can force the old behavior by starting
the template with <code class="inline-code">&lt;#ftl
strict_syntax=false&gt;</code>. (For more information about
why strict syntax is better than old syntax <a href="ref_depr_oldsyntax.html">read this...</a>)</p>
</li>
<li>
<p>New <code class="inline-code">CacheStorage</code> implementation:
<code class="inline-code">freemarker.cache.MruCacheStorage</code>. This cache
storage implements a two-level Most Recently Used cache. In the
first level, items are strongly referenced up to the specified
maximum. When the maximum is exceeded, the least recently used
item is moved into the second level cache, where they are softly
referenced, up to another specified maximum.
<code class="inline-code">freemarker.cache.SoftCachseStorage</code> and
<code class="inline-code">StrongCachseStorage</code> are deprected,
<code class="inline-code">MruCachseStorage</code> is used everywhere instead.
The default cache storage is now an
<code class="inline-code">MruCachseStorage</code> object with 0 strong size,
and infinite soft size.
<code class="inline-code">Configuration.setSetting</code> for
<code class="inline-code">cache_storage</code> now understands string values
as <code class="inline-code">&quot;strong:200, soft:2000&quot;</code>.</p>
</li>
<li>
<p>For <code class="inline-code">BeansWrapper</code> generated models, you
can now use the <code class="inline-code">${obj.method(args)}</code> syntax to
invoke methods whose return type is <code class="inline-code">void</code>.
<code class="inline-code">void</code> methods now return
<code class="inline-code">TemplateModel.NOTHING</code> as their return
value.</p>
</li>
<li>
<p><code class="inline-code">freemarker.template.SimpleHash</code> now can
wrap read-only <code class="inline-code">Map</code>-s, such as the map of HTTP
request parameters in Servlet API.</p>
</li>
<li>
<p>The <code class="inline-code">TemplateNodeModel</code> interface was
introduced to support recursive processing of trees of nodes.
Typically, this will be used in relation to XML.</p>
</li>
<li>
<p>New package: <code class="inline-code">freemarker.ext.dom</code>. This
contains the new XML wrapper, that supports the processing of
XML documents using the visitor pattern (i.e. with
<code class="inline-code">&lt;#visit <em class="code-color">...</em>&gt;</code>
and similar directives), and to provide more convenient XML
traversing as the legacy wrapper. See the <a href="xgui.html">XML processing guide</a> for more
details.</p>
</li>
<li>
<p>New package: <code class="inline-code">freemarker.core</code>. Classes
used by mostly power-users was moved here from the
<code class="inline-code">freemarker.template</code> package. The main reason
of the splitting of <code class="inline-code">freemarker.template</code>
package was that the amount of &quot;expert&quot; public classes and
interfaces grows too much, as we introduce API-s for third-party
tools, such as debugging API.</p>
</li>
<li>
<p>New package: <code class="inline-code">freemarker.debug</code>. This
provides a debugging API, by which you can debug executing
templates through network (RMI). You have to write the front-end
(client), as the API is just the server side. For more
information please read the JavaDoc of the
<code class="inline-code">freemarker.debug</code> package.</p>
</li>
<li>
<p>You can query the FreeMarker version number with static
method <code class="inline-code">Configuration.getVersionNumber()</code>.
Also, the <code class="inline-code">Manifest.mf</code> included in
<code class="inline-code">freemarker.jar</code> now contains the FreeMarker
version number, furthermore, executing it with <code class="inline-code">java
-jar freemarker.jar</code> will print the version number to
the stdout.</p>
</li>
<li>
<p>Added a new protected <code class="inline-code">FreemarkerServlet</code>
method: <code class="inline-code">Configuration
getConfiguration()</code>.</p>
</li>
<li>
<p>Date support is now labeled as final. (It was experimental
earlier.)</p>
</li>
<li>
<p>The <code class="inline-code">BeansWrapper</code> has been improved to
prevent some security exceptions when introspecting.</p>
</li>
<li>
<p>Other minor quality improvements and extensions...</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_231">Other changes</h2>
<ul>
<li>
<p>Fixes and improvements in the Manual and in the API
JavaDoc.</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_232">The history of the releases before the final version</h2>
<h3 class="content-header header-section3" id="autoid_233">Differences between the final release and Release Candidate
4</h3>
<ul>
<li>
<p>Added a new special variable to print the FreeMarker
version number: <code class="inline-code">version</code>. See more <a href="ref_specvar.html">in the reference...</a></p>
</li>
<li>
<p>Minor documentation fixes and improvements.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_234">Differences between the Release Candidate 4 and Release
Candidate 3</h3>
<ul>
<li>
<p>The <code class="inline-code">BeansWrapper</code> has been improved to
prevent some security exceptions when introspecting.</p>
</li>
<li>
<p>The <code class="inline-code">FreemarkerXmlTask</code> has two new
sub-tasks that can be used to prepare template execution with
Jython scripts: <code class="inline-code">prepareModel</code> and
<code class="inline-code">prepareEnvironment</code>. The
<code class="inline-code">jython</code> sub-task is now deprecated, and does
the same as <code class="inline-code">prepareEnvironment</code>. See the
Java API documentation for more details.</p>
</li>
<li>
<p>New special variable to read the FreeMarker version
number: <code class="inline-code">version</code>. See more <a href="ref_specvar.html">in the reference...</a></p>
</li>
<li>
<p>Bugfix: Greater-than sign doesn&#39;t confuse the
<code class="inline-code">eval</code> built-in anymore.</p>
</li>
<li>
<p>Bugfix: The <code class="inline-code">BeansWrapper</code> now wrapps
the <code class="inline-code">null</code> return values of methods
appropriately.</p>
</li>
<li>
<p>Bugfix: The <code class="inline-code">FreemarkerXmlTask</code> doesn&#39;t
need Jython classes anymore, unless you really use Jython
scripts. Several other bugfixes in the Jython related
features.</p>
</li>
<li>
<p>Bugfix: If the template exception handler has ignored
the exception, errors occurring in interpolations inside FTL
tags (e.g. <code class="inline-code">&lt;#if &quot;foo${badVar}&quot; !=
&quot;foobar&quot;&gt;</code>) were handled in the same way as errors
occuring in interpolations outside FTL tags. Thus, the
directive call was not skipped, and the problematic
interpolation was replaced with an empty string. (This was
inconsistent with the behavior of <code class="inline-code">&lt;#if
&quot;foo&quot;+badVar != &quot;foobar&quot;&gt;</code>, which should be 100%
equivalent with the previous example.)</p>
</li>
<li>
<p>Bugfix: The <code class="inline-code">FileTemplateLoader</code> is now
more robust when it receives paths that are malformed
according the native file system. In the earlier version such
paths sometimes caused unexpected
<code class="inline-code">IOException</code> that aborted the searching for
the template in further
<code class="inline-code">FileTemplateLoader</code>-s when you use the
<code class="inline-code">MultiTemplateLoader</code>.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_235">Differences between the Release Candidate 3 and Release
Candidate 2</h3>
<ul>
<li>
<p>Bugfix: Fixing a fatal bug in the template cache that
was introduced with the latest cache bugfix. The template
cache has always reloaded the unchanged template when the
update delay has been elapsed, until the template has been
actually changed, in which case it has never reloaded the
template anymore.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_236">Differences between the Release Candidate 2 and Release
Candidate 1</h3>
<ul>
<li>
<p>Bugfix: The template cache didn&#39;t reload the template
when it was replaced with an older version.</p>
</li>
<li>
<p>API JavaDoc fix: date/time related classes/interfaces
were marked as experimental. They are not experimental.</p>
</li>
<li>
<p>Minor site improvements.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_237">Differences between the Release Candidate 1 and Preview 16
releases</h3>
<ul>
<li>
<p><em>Warning! Non-backward-compatible
change!</em> The default (initial) value of the
<code class="inline-code">strict_syntax</code> setting has been changed from
<code class="inline-code">false</code> to <code class="inline-code">true</code>. When
<code class="inline-code">strict_syntax</code> is <code class="inline-code">true</code>,
tags with old syntax as <code class="inline-code">&lt;include
&quot;foo.ftl&quot;&gt;</code> will be considered as static text (so
they go to the output as-is, like HTML tags do), and not as
FTL tags. Such tags have to be rewritten to
<code class="inline-code">&lt;#include &quot;foo.ftl&quot;&gt;</code>, since only
parts that starts with <code class="inline-code">&lt;#</code>,
<code class="inline-code">&lt;/#</code>, <code class="inline-code">&lt;@</code>, or
<code class="inline-code">&lt;/@</code> count as FTL tags. Or, to recover
the old transitional behavior, where both legacy and new tag
syntax was recognized, you have to explicitly set
<code class="inline-code">strict_syntax</code> to <code class="inline-code">false</code>:
<code class="inline-code">cfg.setStrictSyntaxMode(false)</code>. Also, for
individual templates you can force the old behavior by
starting the template with <code class="inline-code">&lt;#ftl
strict_syntax=false&gt;</code>. (For more information about
why strict syntax is better than old syntax <a href="ref_depr_oldsyntax.html">read this...</a>)</p>
</li>
<li>
<p>New parameter to the <a href="ref_directive_ftl.html"><code>ftl</code>
directive</a>: <code class="inline-code">attributes</code>. The value of
this attribute is a hash that associates arbitrary attributes
(name-value pairs) to the template. The values of the
attributes can be of any type (string, number, sequence...
etc.). FreeMarker doesn&#39;t try to understand the meaning of the
attributes. It&#39;s up to the application that encapsulates
FreeMarker (as a Web application framework). Thus, the set of
allowed attributes and their semantic is application (Web
application framework) dependent.</p>
</li>
<li>
<p>Bugfix:
<code class="inline-code">freemarker.template.utility.DeepUnwrap</code>
unwrapped sequences to empty
<code class="inline-code">ArrayList</code>-s.</p>
</li>
<li>
<p>Bugfix: If you included/imported a template with
<code class="inline-code">*/</code> in path (acquisition), and that template
in turn itself included/imported another template with
<code class="inline-code">*/</code> in path, it may failed.</p>
</li>
<li>
<p>New methods to the
<code class="inline-code">freemarker.core.Environment</code>:
<code class="inline-code">importLib(Template loadedTemplate, java.lang.String
namespace)</code>,
<code class="inline-code">getTemplateForImporting(...)</code>,
<code class="inline-code">getTemplateForInclusion(...)</code>.</p>
</li>
<li>
<p>Improvements in the
<code class="inline-code">java.io.IOException</code> related error messages
of the <code class="inline-code">include</code> and
<code class="inline-code">import</code> directives.</p>
</li>
<li>
<p>Minor improvements in the documentation.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_238">Differences between the Preview 16 and Preview 15
releases</h3>
<ul>
<li>
<p>New package: <code class="inline-code">freemarker.debug</code>. This
provides a debugging API, by which you can debug executing
templates through network (RMI). You have to write the
front-end (client), as the API is just the server side. For
more information please read the JavaDoc of the
<code class="inline-code">freemarker.debug</code> package. (The debugging
API is present for a while, just I forgot to announce it in
the version history. Sorry for that.)</p>
</li>
<li>
<p>Bugfix: With the new XML wrapper,
<code class="inline-code">@@markup</code> and similar special keys:</p>
<ul>
<li>
<p>have returned
<code class="inline-code">&lt;foo&gt;&lt;/foo&gt;</code> for empty
elements instead of <code class="inline-code">&lt;foo /&gt;</code>.
Other than it was needlessly verbose, it has confused
browsers if you generate HTML.</p>
</li>
<li>
<p>have showed the attributes that have no explicitly
given value in the original document, just a default value
coming form the DTD.</p>
</li>
<li>
<p>have forgot to put space before the system
identifier in the <code class="inline-code">&lt;!DOCTYPE
<em class="code-color">...</em>&gt;</code>.</p>
</li>
</ul>
</li>
<li>
<p>Bugfix: XPath with Jaxen has died with
<code class="inline-code">NullPointerException</code> if the context was an
empty node set.</p>
</li>
<li>
<p>A bit more intelligent Xalan XPath error
messages.</p>
</li>
<li>
<p>Revoked fallback-to-classloader logic from the template
cache.</p>
</li>
<li>
<p>From now on, if no XPath engine is available, and the
hash key in an XML query can&#39;t be interpreted without XPath,
an error will tell this clearly, rather than silently
returning undefined variable (null).</p>
</li>
<li>
<p>Bugfix: Some templates have caused the parser to
die.</p>
</li>
<li>
<p>Some other minor improvements here and there...</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_239">Differences between the Preview 15 and Preview 14
releases</h3>
<ul>
<li>
<p>Bugfix: The new default template cache storage
(<code class="inline-code">MruCacheStorage</code>) has started to
continually fail with <code class="inline-code">NullPointerException</code>
from a random point of time, usually when the memory usage was
high in the JVM.</p>
</li>
<li>
<p>Bugfix: In error messages, when the quoted FTL directive
had nested content, that was quoted as well, so the quotation
could be very long and expose nested lines needlessly.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_240">Differences between the Preview 14 and Preview 13
releases</h3>
<ul>
<li>
<p><code class="inline-code">freemarker.template.TemplateMethodModel.exec</code>
now returns <code class="inline-code">Object</code> instead of
<code class="inline-code">TemplateModel</code>.</p>
</li>
<li>
<p>Fixes and improvements for XPath with Jaxen (not Xalan).
Non-node-set XPath expressions are now working. FreeMarker
variables are accessible in XPath expressions with XPath
variable references (e.g.
<code class="inline-code">doc[&quot;book/chapter[title=$currentTitle]&quot;]</code>).</p>
</li>
<li>
<p><code class="inline-code">freemarker.cache.SoftCachseStorage</code>
and <code class="inline-code">StrongCachseStorage</code> is deprected. The
more flexible <code class="inline-code">MruCachseStorage</code> is used
instead everywhere. The default cache storage is now an
<code class="inline-code">MruCachseStorage</code> object with 0 strong size,
and infinite soft size.
<code class="inline-code">Configuration.setSetting</code> for
<code class="inline-code">cache_storage</code> now understands string values
as <code class="inline-code">&quot;strong:200, soft:2000&quot;</code>.</p>
</li>
<li>
<p>Bugfix:
<code class="inline-code">freemarker.cache.MruCachseStorage</code> has died
with <code class="inline-code">ClassCastException</code> sometimes.</p>
</li>
<li>
<p>New built-ins for Java and JavaScript string escaping:
<a href="ref_builtins_string.html#ref_builtin_j_string">j_string</a> and <a href="ref_builtins_string.html#ref_builtin_js_string">js_string</a></p>
</li>
<li>
<p><code class="inline-code">freemarker.template.TemplateExceptionHandler.HTML_DEBUG_HANDLER</code>
now prints more HTML-context-proof messages.</p>
</li>
<li>
<p>You can query the FreeMarker version number with static
method <code class="inline-code">Configuration.getVersionNumber()</code>.
Also, the <code class="inline-code">Manifest.mf</code> included in
<code class="inline-code">freemarker.jar</code> now contains the FreeMarker
version number, furthermore, executing it with <code class="inline-code">java
-jar freemarker.jar</code> will print the version number to
the stdout.</p>
</li>
<li>
<p>Added a new protected
<code class="inline-code">FreemarkerServlet</code> method:
<code class="inline-code">Configuration getConfiguration()</code>.</p>
</li>
<li>
<p>Bugfix: FreeMarker has frozen on empty conditional
blocks in certain contexts.</p>
</li>
<li>
<p>Bugfix: Methods called twice on an object using the
<code class="inline-code">list</code> directive, as
<code class="inline-code">parent.getChildren()</code> with
<code class="inline-code">&lt;#list parent.children as child&gt;
...&lt;/#list&gt;</code></p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_241">Differences between the Preview 13 and Preview 12
releases</h3>
<ul>
<li>
<p>White-space stripping is now more aggressive as before:
it always removes leading and trailing white-space if the line
only contains FTL tags. (Earlier the white-space was not
removed if the tag was <code class="inline-code">&lt;#include
<em class="code-color">...</em>&gt;</code> or user-defined
directive tag with empty directive syntax as
<code class="inline-code">&lt;@myMacro/&gt;</code> (or its equivalents:
<code class="inline-code">&lt;@myMacro&gt;&lt;/@myMacro&gt;</code> and
<code class="inline-code">&lt;@myMacro&gt;&lt;/@&gt;</code>). Now
white-space is removed in these cases as well.) Also,
top-level white-space that separates macro definitions and/or
assignments is now ignored. More information: <a href="dgui_misc_whitespace.html#dgui_misc_whitespace_stripping">Template Author&#39;s Guide/Miscellaneous/White-space handling/White-space stripping</a></p>
</li>
<li>
<p>White-space stripping can be disabled for a single line
with the <a href="ref_directive_nt.html#ref.directive.nt"><code>nt</code></a>
directive (for No Trim).</p>
</li>
<li>
<p>A new directive for the declarative XML processing:
<a href="ref_directive_visit.html#ref.directive.fallback"><code>fallback</code></a></p>
</li>
<li>
<p><code class="inline-code">freemarker.template.SimpleHash</code> now
can wrap read-only <code class="inline-code">Map</code>-s, such as the map
of HTTP request parameters in Servlet API.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_242">Differences between the Preview 12 and Preview 11
releases</h3>
<p>The only change between this and the previous preview
release is that Preview 11 had a bug where DOM trees would
<em>never</em> be garbage-collected.</p>
<h3 class="content-header header-section3" id="autoid_243">Differences between the Preview 11 and Preview 10
releases</h3>
<ul>
<li>
<p>Many XML related changes. Some of them are incompatible
with the previous preview releases! For a more detailed
explanation of how XML related features now work, see: <a href="xgui.html">XML Processing Guide</a></p>
<ul>
<li>
<p>Attention! Attribute queries such as
<code class="inline-code">foo.@bar</code> now return sequences
(similarly to child element queries and XPath queries),
not single nodes. Because of the rule with node sequences
of size 1, it is still good to write
<code class="inline-code">${foo.@bar}</code>, but built-ins such as
<code class="inline-code">?exists</code>, <code class="inline-code">?if_exists</code>
or <code class="inline-code">?default</code> don&#39;t work as before. For
example, instead of
<code class="inline-code">foo.@bar?default(&#39;black&#39;)</code>, you now have
to write <code class="inline-code">foo.@bar[0]?default(&#39;black&#39;)</code>.
So if you have used existence built-ins with attributes,
you have to find those occurrences in the templates and
add that <code class="inline-code">[0]</code>.</p>
</li>
<li>
<p>Attention! XML name-space handling has been totally
reworked and is absolutely incompatible with pre 10. Don&#39;t
worry about this if none of your XML input documents use
you use <code class="inline-code">xmlns</code> attributes. Worry,
though, if you have utilized the "loose
mode", where only the local name of elements were
compared, because that&#39;s now gone. Sorry...</p>
</li>
<li>
<p>Attention! Special-keys <code class="inline-code">@@</code> and
<code class="inline-code">@*</code> now return a sequence of attribute
nodes instead of the hash of them.</p>
</li>
<li>
<p>Several hash keys are now working for node sequences
that store multiple nodes. For example, to get the list of
all <code class="inline-code">para</code> elements of all
<code class="inline-code">chapter</code>-s, just write
<code class="inline-code">doc.book.chapter.para</code>. Or, to get list
of title attributes of all <code class="inline-code">chapter</code>-s
write <code class="inline-code">doc.book.chapter.@title</code>.</p>
</li>
<li>
<p>New special hash keys: <code class="inline-code">**</code>,
<code class="inline-code">@@start_tag</code>,
<code class="inline-code">@@end_tag</code>,
<code class="inline-code">@@attribute_markup</code>,
<code class="inline-code">@@text</code>,
<code class="inline-code">@@qname</code>.</p>
</li>
<li>
<p><code class="inline-code">?parent</code> for attribute nodes now
returns the element node the attribute node belongs
to.</p>
</li>
<li>
<p>You can use Jaxen instead of Xalan for XPath
expressions, if you call the static
<code class="inline-code">freemarker.ext.dom.NodeModel.useJaxenXPathSupport()</code>
method once. We plan to use Jaxen automatically instead of
Xalan if it is available, just the Jaxen support is not
fully functional yet.</p>
</li>
</ul>
</li>
<li>
<p>New special variable: <code class="inline-code">.vars</code>. This is
useful to read top-level variables with square bracket syntax,
for example <code class="inline-code">.vars[&quot;name-with-hyphens&quot;]</code> and
<code class="inline-code">.vars[dynamicName]</code>.</p>
</li>
<li>
<p>New built-in, <code class="inline-code">eval</code>, to evaluate a
string as FTL expression. For example
<code class="inline-code">&quot;1+2&quot;?eval</code> returns the number 3.</p>
</li>
<li>
<p><code class="inline-code">FreemarkerServlet</code> now uses the
configuration&#39;s <code class="inline-code">locale</code> setting, rather than
<code class="inline-code">Locale.getDefault()</code>, to set the locale of
the templates. Also, the signature of the
<code class="inline-code">deduceLocale</code> method has been
changed.</p>
</li>
<li>
<p>We have a new (beta status)
<code class="inline-code">CacheStorage</code> implementation:
<code class="inline-code">freemarker.cache.MruCacheStorage</code>. This
cache storage implements a two-level Most Recently Used cache.
In the first level, items are strongly referenced up to the
specified maximum. When the maximum is exceeded, the least
recently used item is moved into the second level cache, where
they are softly referenced, up to another specified maximum.
You can plug to try it with <code class="inline-code">cfg.setCacheStorage(new
freemarker.cache.MruCacheStorage(maxStrongSize,
maxSoftSize))</code>.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_244">Differences between the Preview 10 and Preview 9
releases</h3>
<ul>
<li>
<p>The special key <code class="inline-code">@@xmlns</code> was removed
in favor of a new FTL directive for the same purpose,
<code class="inline-code">&lt;#xmlns...&gt;</code>.</p>
</li>
<li>
<p>By default, the system is stricter about the use of
namespace prefixes. In general, you must use a prefix to
qualify subelements that are associated with an XML
nampespace. You can do this with the new
<code class="inline-code">&lt;#xmlns...&gt;</code> directive, but prefixes
declared in the input XML doc will actually work with no
declaration.</p>
</li>
<li>
<p>Introduced a new special key called
<code class="inline-code">@@text</code> that returns all the text nodes
contained (recursively) in an element all concatenated
together.</p>
</li>
<li>
<p>Either Jaxen or Xalan can be used to provide XPath
functionality. Prior versions only worked with Xalan.</p>
</li>
<li>
<p>The <code class="inline-code">FreemarkerServlet</code> uses
<code class="inline-code">ObjectWrapper.DEFAULT_WRAPPER</code> by default
instead of <code class="inline-code">ObjectWrapper.BEANS_WRAPPER</code>.
What this means is that, by default, objects of type
<code class="inline-code">java.lang.String</code>,
<code class="inline-code">java.lang.Number</code>,
<code class="inline-code">java.util.List</code>, and
<code class="inline-code">java.util.Map</code> will be wrapped as
<code class="inline-code">TemplateModels</code> via the classes
<code class="inline-code">SimpleScalar</code>,
<code class="inline-code">SimpleNumber</code>,
<code class="inline-code">SimpleSequence</code>, and
<code class="inline-code">SimpleHash</code> respectively. Thus, the java
methods on those objects will not be available. The default
wrapper implementation in FreeMarker 2.3 automatically knows
how to wrap Jython objects, and also wraps
<code class="inline-code">org.w3c.dom.Node</code> objects into instances of
<code class="inline-code">freemarker.ext.dom.NodeModel</code>.</p>
</li>
<li>
<p>The <code class="inline-code">FreemarkerServlet</code> base
implementation no longer deduces the locale to use from the
HttpRequest.getLocale() hook. Rather, it simply delegates to a
<code class="inline-code">deduceLocale()</code> hook that is overridable in
subclasses. The base implementation simply uses
<code class="inline-code">Locale.getDefault()</code></p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_245">Differences between the Preview 9 and Preview 8
releases</h3>
<ul>
<li>
<p>Fixed bugs introduced with Preview 8: XPath,
<code class="inline-code">@@markup</code> and
<code class="inline-code">@@nested_markup</code> now works with the document
node.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_246">Differences between the Preview 8 and Preview 7
releases</h3>
<ul>
<li>
<p><code class="inline-code">macro</code> and assignment directives now
accept arbitrary destination variable name with quoted syntax.
For example: <code class="inline-code">&lt;#macro
&quot;foo-bar&quot;&gt;<em class="code-color">...</em></code> or
<code class="inline-code">&lt;#assign &quot;this+that&quot; = 123&gt;</code>. This is
important, because XML element names can contain hyphen, and
it was not possible to define a handler macro for those
elements, till now.</p>
</li>
<li>
<p>Special key <code class="inline-code">@@content</code> was renamed to
<code class="inline-code">@@nested_markup</code>.</p>
</li>
<li>
<p>Fixed outdated XML related Manual parts (that were
outdated even in Preview 7).</p>
</li>
<li>
<p>Better parse-error messages.</p>
</li>
<li>
<p>Minor bugfixes here and there...</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_247">Differences between the Preview 7 and Preview 6
releases</h3>
<ul>
<li>
<p>Caching of XPath queries should lead to significant
performance improvements for XML processing, at least when
XPath is heavily used.</p>
</li>
<li>
<p>Refinements in handling of XML namespaces in the XML
processing functionality. The new
<code class="inline-code">strict_namespace_handling</code> setting
introduced in 2.3pre6 was removed. A general-purpose solution
was arrived at that should make that configuration setting
unnecessary.</p>
</li>
<li>
<p>Special key <code class="inline-code">@xmlns</code> was renamed to
@@xmlns. Reserved namespace prefix <code class="inline-code">default</code>
was renamed to <code class="inline-code">@@default</code>.</p>
</li>
<li>
<p>The <code class="inline-code">ftl</code> directive now accepts
non-string types.</p>
</li>
<li>
<p>New special keys were introduced for XML node wrappers
in the freemarker.ext.dom package. The
<code class="inline-code">@@markup</code> key returns the literal markup
that make up that element and the <code class="inline-code">@@content</code>
key returns all the element&#39;s markup excluding the opening and
closing tags.</p>
</li>
<li>
<p>Minor bugfixes here and there...</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_248">Differences between the Preview 6 and Preview 5
releases</h3>
<ul>
<li>
<p>Existence built-ins (<code class="inline-code">?default</code>,
<code class="inline-code">?exists</code>, etc.) now work with sequence sub
variables as well. Read the <a href="ref_directive_switch.html#ref.directive.default">documentation of the
<code>default</code> built-in</a> for more
information.</p>
</li>
<li>
<p>The <code class="inline-code">matches</code> built-in now returns a
sequence instead of a collection.</p>
</li>
<li>
<p>Refinements in handling of XML namespaces in the XML
processing functionality. A new setting,
<code class="inline-code">strict_namespace_handling</code> was introduced.
If this is set (it is off by default) any node-handling macro
used in with the visit/recurse machinery must be from a macro
library that declares in its ftl header that it handles the
namespace in question.</p>
</li>
<li>
<p>Minor bugfixes here and there...</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_249">Differences between the Preview 5 and Preview 4
releases</h3>
<ul>
<li>
<p>The <code class="inline-code">replace</code> and
<code class="inline-code">split</code> built-ins now support
case-insensitive comparison and regular expressions (J2SE 1.4+
only), and some other new options. More information can be
found <a href="ref_builtins_string.html#ref_builtin_string_flags">here</a>.</p>
</li>
<li>
<p>New butilt-in for regular expression matching (J2SE 1.4+
only): <a href="ref_builtins_string.html#ref_builtin_matches"><code>matches</code></a></p>
</li>
<li>
<p>Minor bugfixes here and there...</p>
</li>
<li>
<p>Manual: More browser-safe HTML-s. More updated
content.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_250">Differences between the Preview 4 and Preview 3
releases</h3>
<ul>
<li>
<p>Bugfix: with multi-type variables, <code class="inline-code">+</code>
operator overload for hash type had higher precedence than the
precedence of some older overloads.</p>
</li>
<li>
<p>The API documentation was missing from the distribution
<code class="inline-code">tar.gz</code>.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_251">Differences between the Preview 3 and Preview 2
releases</h3>
<ul>
<li>
<p>XML processing: Many various bugfixes, especially with
the declarative processing.</p>
</li>
<li>
<p>XML processing: the <code class="inline-code">namespace_uri</code>
built-in, the <code class="inline-code">xmlnsuri</code> header parameter,
and the <code class="inline-code">TemplateNodeModel.getNodeNamespace</code>
method were renamed to <code class="inline-code">node_namespace</code> and
<code class="inline-code">getNodeNamespace</code> respectively.</p>
</li>
<li>
<p>XML processing: Better documentation. Especially, note:
<a href="xgui.html">XML Processing Guide</a></p>
</li>
<li>
<p>A new header parameter, <code class="inline-code">strip_text</code>,
that removes all top-level text from a template. See <a href="ref_directive_ftl.html#ref.directive.ftl"><code>ftl</code>
directive</a></p>
</li>
<li>
<p>Support for a variable number of macro parameters. If
the last parameter in a macro declaration ends with
<code class="inline-code">...</code>, all extra parameters passed to the
macro will be available via that parameter. For macros called
with positional parameters, the parameter will be a sequence.
For named parameters, the parameter will be a hash.</p>
</li>
<li>
<p>For <code class="inline-code">BeansWrapper</code> generated models,
you can now use the <code class="inline-code">${obj.method(args)}</code>
syntax to invoke methods whose return type is
<code class="inline-code">void</code>. <code class="inline-code">void</code> methods now
return <code class="inline-code">TemplateModel.NOTHING</code> as their
return value.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_252">Differences between the Preview 2 and Preview 1
releases</h3>
<ul>
<li>
<p>The <code class="inline-code">freemarker.ext.dom.NodeModel</code> API
changed slightly. The <code class="inline-code">setDocumentBuilder()</code>
method was changed to
<code class="inline-code">setDocumentBuilderFactory()</code> because the
older scheme was not thread-safe. The
<code class="inline-code">stripComments</code> and
<code class="inline-code">stripPIs</code> methods are renamed to The
<code class="inline-code">removeComments</code> and
<code class="inline-code">removePIs</code>, and are fixed now. A new method,
<code class="inline-code">simplify</code> has been added.</p>
</li>
<li>
<p>The expressions <code class="inline-code">as</code>,
<code class="inline-code">in</code>, and <code class="inline-code">using</code> are now
keywords in the template language and cannot be used as
top-level variable names without square-bracket syntax (as
<code class="inline-code">.vars[&quot;in&quot;]</code>). If, by some chance, you have
top-level variables that use one of these names, you will have
to rename them (or use the square-bracket syntax). Sorry for
the inconvenience.</p>
</li>
<li>
<p>The <code class="inline-code">?new</code> built-in, as it was
implemented, was a security hole. Now, it only allows you to
instantiate a java object that implements the
<code class="inline-code">freemarker.template.TemplateModel</code>
interface. If you want the functionality of the
<code class="inline-code">?new</code> built-in as it existed in prior
versions, make available an instance of the new
<code class="inline-code">freemarker.template.utility.ObjectConstructor</code>
class to your template.</p>
</li>
<li>
<p>The <code class="inline-code">&lt;#recurse&gt;</code> directive was
broken. It did not work with a <code class="inline-code">using</code>
clause. This is now fixed.</p>
</li>
</ul>
<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="versions_2_3_1.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_2_8.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>