blob: 0b092b948f779077efe9814e1dfd01287b606d94 [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.2 - 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="FreeMarker Manual">
<meta property="og:title" content="2.2">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="http://example.com/versions_2_2.html">
<link rel="canonical" href="http://example.com/versions_2_2.html">
<link rel="icon" href="favicon.png" type="image/png">
<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338517553">
</head>
<body itemscope itemtype="https://schema.org/Code">
<meta itemprop="url" content="http://example.com/">
<meta itemprop="name" content="FreeMarker Manual">
<!--[if lte IE 9]>
<div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
<![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">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">Versions</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="versions_2_2.html"><span itemprop="name">2.2</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><li><a href="alphaidx.html">Index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="ref.html">Reference</a></li><li><a href="app_faq.html">FAQ</a></li><li><a href="preface.html#test_target">Bőregér</a></li></ul></div></div></div> <div class="main-content site-width">
<div class="content-wrapper no-toc">
<div id="table-of-contents-wrapper" class="col-left">
</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_2_1.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_1_5.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="versions_2_2" itemprop="headline">2.2</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#autoid_208" data-menu-target="autoid_208">Non backward-compatible changes!</a></li><li><a class="page-menu-link" href="#autoid_209" data-menu-target="autoid_209">Changes in FTL (FreeMarker Template Language)</a></li><li><a class="page-menu-link" href="#autoid_210" data-menu-target="autoid_210">Changes on the Java side</a></li><li><a class="page-menu-link" href="#autoid_211" data-menu-target="autoid_211">Other changes</a></li><li><a class="page-menu-link" href="#autoid_212" data-menu-target="autoid_212">The history of the releases before the final version</a><ul><li><a class="page-menu-link" href="#autoid_213" data-menu-target="autoid_213">Differences between the final and RC2 releases</a></li><li><a class="page-menu-link" href="#autoid_214" data-menu-target="autoid_214">Differences between the RC2 and RC1 releases</a></li><li><a class="page-menu-link" href="#autoid_215" data-menu-target="autoid_215">Differences between the Preview 2 and RC1 releases</a></li><li><a class="page-menu-link" href="#autoid_216" data-menu-target="autoid_216">Differences between the Preview 1 and Preview 2
releases</a></li></ul></li></ul> </div><p>Date of release: 2003-03-27</p><p>This release introduces some really important new features.
Unfortunately, evolution was painful again; we have a few non-backward
compatible changes (see below). Also, for those of you awaiting
desired native date/time type, sorry, it is still not here (because of
some internal chaos in the team... stand by, it&#39;s coming).</p>
<h2 class="content-header header-section2" id="autoid_208">Non backward-compatible changes!</h2>
<ul>
<li>
<p>Macros are now plain variables. This means that if you are
unlucky and you have both a macro and another variable with the
same name, now the variable will overwrite the macro, so your
old template will malfunction. If you have a collection of
common macros, you should use the new <a href="dgui_misc_namespace.html">namespace feature</a> to
prevent accidental clashes with the variables used in the
templates.</p>
</li>
<li>
<p>With the introduction of the new <a href="dgui_misc_namespace.html">namespace support</a>,
<code class="inline-code">global</code> and <code class="inline-code">assign</code>
directives are no longer synonyms. <code class="inline-code">assign</code>
creates a variable in the current <code class="inline-code">namespace</code>,
while <code class="inline-code">global</code> creates variable that is visible
from all namespaces (as if the variable would be in the
data-model). Thus, the variable created with
<code class="inline-code">assign</code> is more specific, and hides the
variable of the same name created with
<code class="inline-code">global</code>. As a result, if you use both
<code class="inline-code">global</code> and <code class="inline-code">assign</code> mixed
for the same variable in your templates, now they will
malfunction. The solution is to search-and-replace all
<code class="inline-code">global</code>s in your old templates with
<code class="inline-code">assign</code>.</p>
</li>
<li>
<p>The reserved hash <code class="inline-code">root</code> no longer exists
as a predefined variable (we no longer have reserved variables).
Use <a href="dgui_template_exp.html#dgui_template_exp_var_special">special
variable expressions</a> to achieve similar effects. However,
we have no equivalent replacement for <code class="inline-code">root</code>
because of the changes in the variable scopes caused by the
introduction of namespaces. You may should use
<code class="inline-code">.globals</code> or
<code class="inline-code">.namespace</code>.</p>
</li>
<li>
<p>The <code class="inline-code">BeansWrapper</code> no longer exposes
native Java arrays, booleans, numbers, enumerations, iterators,
and resource bundles as <code class="inline-code">TemplateScalarModel</code>.
This way, number objects wrapped through
<code class="inline-code">BeansWrapper</code> are subject to FreeMarker&#39;s
number formatting machinery. Also, booleans can be formatted
using the <code class="inline-code">?string</code> built-in.</p>
</li>
<li>
<p>The signature of
<code class="inline-code">Configuration.setServletContextForTemplateLoading</code>
has been changed: the first parameter is now
<code class="inline-code">Object</code> instead of
<code class="inline-code">javax.servlet.ServletContext</code>. Thus, you have
to recompile your classes that call this method. The change was
required to prevent class-loading failure when
<code class="inline-code">javax.servlet</code> classes are not available and
you would not call this method.</p>
</li>
<li>
<p>This release introduces a <a href="dgui_misc_whitespace.html">parse-time white-space
remover</a> that strips some of the typical superfluous
white-space around FreeMarker tags and comments. <em>This
feature is on by default!</em> Most probably this will not
cause problems if you generate white-space neutral output like
HTML. But if it does cause undesirable reformatting in output
you generate, you can disable it with
<code class="inline-code">config.setWhitespaceStripping(false)</code>. Also,
you can enable/disable it on a per-template basis with the new
<a href="ref_directive_ftl.html#ref.directive.ftl"><code>ftl</code></a>
directive.</p>
</li>
<li>
<p>Some new directives were introduced:
<code class="inline-code">nested</code>, <code class="inline-code">import</code>,
<code class="inline-code">escape</code>, <code class="inline-code">noescape</code>,
<code class="inline-code">t</code>, <code class="inline-code">rt</code>,
<code class="inline-code">lt</code>. This means that if you are unlucky and
the text of your template contains something like
<code class="inline-code">&lt;nested&gt;</code>, then that will be
misinterpreted as a directive. To prevent this kind of problem
in the future, we recommend everybody to switch from the old
syntax to the new syntax (``strict syntax&#39;&#39;). The strict syntax
will be the the default syntax starting from some of the later
releases anyway. We plan to release a conversion tool for
converting old templates. For more information please read:
<a href="ref_depr_oldsyntax.html">Reference/Deprecated FTL constructs/Old FTL syntax</a></p>
</li>
<li>
<p>The data-model created by the
<code class="inline-code">FreemarkerServlet</code> now uses automatic scope
discovery, so writing
<code class="inline-code">Application.<em class="code-color">attrName</em></code>,
<code class="inline-code">Session.<em class="code-color">attrName</em></code>,
<code class="inline-code">Request.<em class="code-color">attrName</em></code>
is no longer mandatory; it&#39;s enough to write
<code class="inline-code"><em class="code-color">attrName</em></code> (for more
information <a href="pgui_misc_servlet.html#topic.servlet.scopeAttr">read
this</a>). This may break an old template if that rely on the
non-existence of certain top-level variables.</p>
</li>
<li>
<p><code class="inline-code">FreemarkerServlet</code> now uses the encoding
of the template file for the output, unless you specify the
encoding in the <code class="inline-code">ContentType</code> init-param, such
as <code class="inline-code">text/html; charset=UTF-8</code>.</p>
</li>
<li>
<p>The format of template paths is now more restricted than
before. The path must not use <code class="inline-code">/</code>,
<code class="inline-code">./</code> and <code class="inline-code">../</code> and
<code class="inline-code">://</code> with other meaning as they have in URL
paths (or in UN*X paths). The characters <code class="inline-code">*</code>
and <code class="inline-code">?</code> are reserved. Also, the template loader
must not want paths starting with <code class="inline-code">/</code>. For more
information please read: <a href="pgui_config_templateloading.html">Programmer&#39;s Guide/The Configuration/Template loading</a></p>
</li>
<li>
<p>Till now
<code class="inline-code">TemplateTransformModel.getWriter</code> has received
null as parameter map if the transform was called without
parameters. From now, it will receive an empty Map instead. Note
that the previous API documentation didn&#39;t state that it always
receives null if there are no parameters, so hopelessly only
very few classes exploit this design mistake.</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_209">Changes in FTL (FreeMarker Template Language)</h2>
<ul>
<li>
<p>User-defined directives: Transform and macro call syntax
has been unified; they can be called in the same way, as
user-defined directives. This also means that macros support
named parameters and nested content (like the -- now deprecated
-- <code class="inline-code">transform</code> directive did). For example, if
you have a macro called <code class="inline-code">sect</code>, you may call it
via <code class="inline-code">&lt;@sect title=&quot;Blah&quot; style=&quot;modern&quot;&gt;Blah
blah...&lt;/@sect&gt;</code>. For more information read:
<a href="dgui_misc_userdefdir.html">Template Author&#39;s Guide/Miscellaneous/Defining your own directives</a></p>
</li>
<li>
<p>Macros are now plain variables. This significantly
simplifies FreeMarker semantics, while providing more
flexibility; for example you can pass macros as parameters to
other macros and transforms. As for the problem of clashing
commonly-used-macro and variable names, we provide a more
powerful solution: namespaces.</p>
</li>
<li>
<p>Namespaces: Names-spaces are invaluable if you want to
assemble collections (``libraries&#39;&#39;) of macros and transforms
(and other variables), and then use them in any template without
worrying about accidental name clashes with the application
specific and temporary variables, or with the variables of other
collections you want to use in the same template. This is
extremely important if FreeMarker users want to share their
macro/transform collections. For more information read: <a href="dgui_misc_namespace.html">Template Author&#39;s Guide/Miscellaneous/Namespaces</a></p>
</li>
<li>
<p>With the introduction of namespaces our variable related
terminology changed. As a result, <code class="inline-code">assign</code> is
no longer synonymous with <code class="inline-code">global</code>. The
<code class="inline-code">assign</code> directive has been undeprecated, and
should be used instead of <code class="inline-code">global</code> almost
everywhere. In the new approach <code class="inline-code">assign</code>
creates variables in the current namespace, while
<code class="inline-code">global</code> creates a variable that is visible
from all namespaces (as if the variable were in the root of the
data-model). A variable created with <code class="inline-code">assign</code>
in the current namespace hides the variable of the same name
that was created with <code class="inline-code">global</code>.</p>
</li>
<li>
<p><code class="inline-code">ftl</code> directive: With this directive you
can give information about the template for FreeMarker, like the
encoding (charset) of the template, the used FTL syntax variant,
etc. Also, this directive helps you to write templates that are
less dependent on FreeMarker configuration settings, also it
helps third-party tools to identify and correctly parse
FreeMarker templates. For more information see: <a href="ref_directive_ftl.html#ref.directive.ftl"><code>ftl</code>
directive</a></p>
</li>
<li>
<p>White-space stripping: FreeMarker now automatically
removes some of the typical superfluous white-spaces around
FreeMarker tags and comments, like the indentation spaces
before- and line-break after <code class="inline-code">&lt;#if ...&gt;</code>
tags. For more information read: <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>New directive to apply a common (&quot;escaping&quot;) expression to
all interpolations in a block: <a href="ref_directive_escape.html#ref.directive.escape"><code>escape</code></a>.
The name comes from the common usage of this directive for
automatic HTML-escaping of interpolations.</p>
</li>
<li>
<p>The new and preferred way of number formatting with
<code class="inline-code">string</code> built-in is
<code class="inline-code">foo?string(format)</code>, instead of the less
natural <code class="inline-code">foo?string[format]</code>.</p>
</li>
<li>
<p>The <code class="inline-code">string</code> built-in works for boolean
values. For example: <code class="inline-code">${spamFilter?string(&quot;enabled&quot;,
&quot;disabled&quot;)}</code>. For more information <a href="ref_builtins_boolean.html#ref_builtin_string_for_boolean">read the
reference</a>.</p>
</li>
<li>
<p>The default strings for outputting boolean value using the
<code class="inline-code">string</code> built-in can be set using the
<code class="inline-code">boolean_format</code> setting.</p>
</li>
<li>
<p>Comments can be placed inside FTL tags and interpolations.
For example: <code class="inline-code">&lt;#assign &lt;#-- a comment --&gt; x =
3&gt;</code></p>
</li>
<li>
<p>All letters and numbers are enabled in variable names,
also <code class="inline-code">$</code> is allowed (as in Java programming
language). Thus you can use accents, Arabic letters, Chinese
letters, etc.</p>
</li>
<li>
<p>String literals can be quoted with apostrophe-quote.
<code class="inline-code">&quot;foo&quot;</code> and <code class="inline-code">&#39;foo&#39;</code> are
equivalent.</p>
</li>
<li>
<p>New <a href="ref_builtins_string.html">string
built-ins</a>: <code class="inline-code">index_of</code>,
<code class="inline-code">last_index_of</code>,
<code class="inline-code">starts_with</code>, <code class="inline-code">ends_with</code>,
<code class="inline-code">replace</code>, <code class="inline-code">split</code>,
<code class="inline-code">chop_linebreak</code>,
<code class="inline-code">uncap_first</code>.</p>
</li>
<li>
<p>New <a href="ref_builtins_sequence.html">sequence
built-ins</a>: <code class="inline-code">sort</code>,
<code class="inline-code">sort_by</code>.</p>
</li>
<li>
<p>New built-ins for experts to check the type of a variable.
See: <a href="ref_builtins_expert.html#ref_builtin_isType"><code>is_<em>...</em></code>
built-ins</a></p>
</li>
<li>
<p>New built-in for experts to create a variable of certain
Java <code class="inline-code">TemplateModel</code> implementation. See: <a href="ref_builtins_expert.html#ref_builtin_new"><code>new</code>
built-in</a></p>
</li>
<li>
<p>New built-in, <a href="ref_builtins_expert.html#ref_builtin_namespace"><code>namespace</code></a>,
to get the namespace of a macro.</p>
</li>
<li>
<p>New expression type: special variable expression. To
prevent backward compatibility problems when we introduce new
predefined variables, from now <a href="dgui_template_exp.html#dgui_template_exp_var_special">special variable
expressions</a> are used to access them.</p>
</li>
<li>
<p>New directives: <code class="inline-code">t</code>,
<code class="inline-code">rt</code> and <code class="inline-code">lt</code> directives allow
you to do explicit white-space removal in extreme FTL
applications. For more information read <a href="ref_directive_t.html#ref.directive.t">the reference</a>.</p>
</li>
<li>
<p><code class="inline-code">assign</code>, <code class="inline-code">local</code> and
<code class="inline-code">global</code> now can capture the output generated
be the nested template fragment into the variable. This
deprecates <code class="inline-code">capture_output</code> transform. More
information: <a href="ref_directive_assign.html#ref.directive.assign">assign
directive reference</a></p>
</li>
<li>
<p>Bulk assignments (as <code class="inline-code">&lt;#assign x=1, y=2,
z=3&gt;</code>) no longer need colon to separate the
assignments (as <code class="inline-code">&lt;#assign x=1 y=2 z=3&gt;</code>),
although it is still allowed to preserve backward
compatibility.</p>
</li>
<li>
<p>Path that contains <code class="inline-code">//:</code> is considered as
absolute path.</p>
</li>
<li>
<p><code class="inline-code">include</code> and
<code class="inline-code">transform</code> directives no longer need a
semicolon to separate the template or transform name from the
parameter list, although it is still allowed to preserve
backward compatibility.</p>
</li>
<li>
<p><code class="inline-code">#</code>-less tag syntax is deprecated (but
still working). That is, you should write
<code class="inline-code">&lt;#<em class="code-color">directive
...</em>&gt;</code> instead of
<code class="inline-code">&lt;<em class="code-color">directive
...</em>&gt;</code>, and
<code class="inline-code">&lt;/#<em class="code-color">directive
...</em>&gt;</code> instead of
<code class="inline-code">&lt;/<em class="code-color">directive
...</em>&gt;</code>. For more info read: <a href="ref_depr_oldsyntax.html">Reference/Deprecated FTL constructs/Old FTL syntax</a></p>
</li>
<li>
<p><code class="inline-code">foreach</code> is depreciated (but still
working). Use <a href="ref_directive_list.html#ref.directive.list"><code>list</code></a>
instead.</p>
</li>
<li>
<p>Bugfix: Undefined variables in hash and sequence
constructors (as <code class="inline-code">[a, b, c]</code>) didn&#39;t caused
errors.</p>
</li>
<li>
<p>Bugfix: String concatenation had performance problem if
there was multiple concatenations chained, as:
<code class="inline-code">&quot;a&quot;+x+&quot;a&quot;+x+&quot;a&quot;+x+&quot;a&quot;+x+&quot;a&quot;+x</code>.</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_210">Changes on the Java side</h2>
<ul>
<li>
<p>Arbitrary JSP custom tags can be used as FreeMarker
transforms in <code class="inline-code">FreemarkerServlet</code>-driven
templates. More information: <a href="pgui_misc_servlet.html">Programmer&#39;s Guide/Miscellaneous/Using FreeMarker with servlets</a></p>
</li>
<li>
<p>Various improvements for
<code class="inline-code">BeansWrapper</code>:</p>
<ul>
<li>
<p>The <code class="inline-code">BeansWrapper</code> no longer exposes
arbitrary objects as
<code class="inline-code">TemplateScalarModel</code>s, only
<code class="inline-code">java.lang.String</code> and
<code class="inline-code">Character</code> objects. This way, number
objects wrapped through <code class="inline-code">BeansWrapper</code> are
subject to FreeMarker&#39;s number formatting machinery. As a
side effect, non-string and non-number objects that were
previously accepted in equality and inequality operations
(because they had a string representation) will now cause
the engine to throw exception on comparison attempt.</p>
</li>
<li>
<p><code class="inline-code">java.lang.Character</code> objects are
exposed as scalars through
<code class="inline-code">BeansWrapper</code>.</p>
</li>
<li>
<p>Experimental feature: With the
<code class="inline-code">setSimpleMapWrapper</code> method of
<code class="inline-code">BeansWrapper</code> you can configure it to wrap
<code class="inline-code">java.util.Map</code>-s as
<code class="inline-code">TemplateHashModelEx</code>-s, and do not expose
the methods of the object.</p>
</li>
</ul>
</li>
<li>
<p><code class="inline-code">TransformControl</code> interface (was
experimental earlier): If the <code class="inline-code">Writer</code> returned
by <code class="inline-code">TemplateTransformModel.getWriter</code>
implements this interface, it can instruct the engine to skip or
to repeat evaluation of the nested content, and gets notified
about exceptions that are thrown during the nested content
evaluation. Note that the <code class="inline-code">onStart</code> and
<code class="inline-code">afterBody</code> methods now are allowed to throw
<code class="inline-code">IOException</code>. For more information please read
the API documentation.</p>
</li>
<li>
<p>Localized lookup can be disabled with the new
<code class="inline-code">Configuration</code> methods:
<code class="inline-code">set/getLocalizedLookup</code>,
<code class="inline-code">clearTemplateCache</code></p>
</li>
<li>
<p>The new interface
<code class="inline-code">freemarker.cache.CacheStorage</code> allows users to
plug custom template caching strategies with the
<code class="inline-code">cache_storage</code> setting. The core package now
ships with two implementations:
<code class="inline-code">SoftCacheStorage</code> and
<code class="inline-code">StrongCacheStorage</code>. For more information
read: <a href="pgui_config_templateloading.html">Programmer&#39;s Guide/The Configuration/Template loading</a></p>
</li>
<li>
<p>You can set settings with string name and string value
with the new <code class="inline-code">setSetting(String key, String
value)</code> method of <code class="inline-code">Configurable</code>
super-classes (as <code class="inline-code">Configuration</code>). Also you
can load settings from <code class="inline-code">.properties</code> file with
the <code class="inline-code">setSettings</code> method.</p>
</li>
<li>
<p>Other new <code class="inline-code">Configuration</code> methods:
<code class="inline-code">clearTemplateCache</code>,
<code class="inline-code">clearSharedVariables</code>,
<code class="inline-code">getTemplateLoader</code>, and
<code class="inline-code">clone</code>.</p>
</li>
<li>
<p>Changes to <code class="inline-code">TemplateTransformModel</code>
interface: <code class="inline-code">getWriter</code> can throw
<code class="inline-code">IOException</code>, and can return
<code class="inline-code">null</code> if the transform does not support body
content.</p>
</li>
<li>
<p>Till now
<code class="inline-code">TemplateTransformModel.getWriter</code> has received
null as parameter map if the transform was called without
parameters. From now, it will receive an empty Map instead. Note
that the previous API documentation didn&#39;t state that it always
receives null if there are no parameters, so hopelessly only
very few classes exploit this design mistake.</p>
</li>
<li>
<p>Various improvements for
<code class="inline-code">FreemarkerServlet</code>:</p>
<ul>
<li>
<p>The data-model now uses automatic scope discovery, so
writing
<code class="inline-code">Application.<em class="code-color">attrName</em></code>,
<code class="inline-code">Session.<em class="code-color">attrName</em></code>,
<code class="inline-code">Request.<em class="code-color">attrName</em></code>
is no longer mandatory; it&#39;s enough to write
<code class="inline-code"><em class="code-color">attrName</em></code>. For
more information <a href="pgui_misc_servlet.html#topic.servlet.scopeAttr">read this</a>.</p>
</li>
<li>
<p><code class="inline-code">FreemarkerServlet</code> now uses the
encoding of the template file for the output, unless you
specify the encoding in the <code class="inline-code">ContentType</code>
init-param, such as <code class="inline-code">text/html;
charset=UTF-8</code>.</p>
</li>
<li>
<p>All <code class="inline-code">Configuration</code> level settings
can by set with Servlet init-params
(<code class="inline-code">template_exception_handler</code>,
<code class="inline-code">locale</code>, <code class="inline-code">number_format</code>,
etc.).</p>
</li>
<li>
<p>The object wrapper the servlet internally uses is now
set as the default object wrapper for its
<code class="inline-code">Configuration</code> instance.</p>
</li>
<li>
<p>It no longer forces session creation for requests that
don&#39;t belong to an existing session, improving
scalability.</p>
</li>
</ul>
</li>
<li>
<p>JDOM independent XML-wrapping:
<code class="inline-code">freemarker.ext.xml.NodeListModel</code> is a
re-implementation of
<code class="inline-code">freemarker.ext.jdom.NodeListModel</code> that does
not rely on JDOM; you don&#39;t need JDOM .jar anymore. The new
<code class="inline-code">NodeListModel</code> automatically uses W3C DOM,
dom4j, or JDOM, depending on which library is available (that
is, depending on what object do you pass to its
constructor).</p>
</li>
<li>
<p>Bugfix: <code class="inline-code">WebappTemplateLoader</code>: Template
updating didn&#39;t worked correctly with Tomcat due the caching of
resources. Now <code class="inline-code">WebappTemplateLoader</code> tries to
access the resources directly as <code class="inline-code">File</code>, if it
is possible, thus bypasses the caching.</p>
</li>
<li>
<p>Various bug-fixes for
<code class="inline-code">FreemarkerServlet</code>:</p>
<ul>
<li>
<p>The servlet now loads the correct template if it was
called through
<code class="inline-code">RequestDispatcher.include</code>.</p>
</li>
<li>
<p>The caching of <code class="inline-code">HttpServletRequest</code>
objects is now compliant with the servlet
specification.</p>
</li>
<li>
<p><code class="inline-code">TemplateException</code>s was suppressed
in certain situations resulting in half-rendered pages
without error message.</p>
</li>
</ul>
</li>
<li>
<p>Bugfix: FreeMarker didn&#39;t work if the
<code class="inline-code">javax.servlet</code> classes was not available,
because <code class="inline-code">Configuration</code> explicitly referred to
<code class="inline-code">javax.servlet.ServletContext</code>.</p>
</li>
<li>
<p>Bugfix: classes may were not found if they was available
only in the <code class="inline-code">WEB-INF</code>, and FreeMarker tried to
load the class dynamically.</p>
</li>
<li>
<p>Bugfix: the <code class="inline-code">Template</code> constructor (and
thus <code class="inline-code">Configuration.getTemplate</code>) sometimes
threw <code class="inline-code">TokenMgrError</code> (a non-checked exception)
instead of <code class="inline-code">ParseException</code>.</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_211">Other changes</h2>
<ul>
<li>
<p>The Web application related examples has been
replaced.</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_212">The history of the releases before the final version</h2>
<h3 class="content-header header-section3" id="autoid_213">Differences between the final and RC2 releases</h3>
<ul>
<li>
<p>You can load settings from
<code class="inline-code">.properties</code> file with the
<code class="inline-code">setSettings</code> method of
<code class="inline-code">Configuration</code> and other
<code class="inline-code">Configurable</code> subclasses.</p>
</li>
<li>
<p>New string built-in:
<code class="inline-code">uncap_first</code></p>
</li>
<li>
<p>Bugfix: When exposing an XML document to a template and
accessing it with XPath using Jaxen a
<code class="inline-code">ClassCastException</code> has occurred.</p>
</li>
<li>
<p>Bugfix: The template cache has loaded templates with bad
<code class="inline-code">Configuration</code> instance in certain
situations if you use not the static default
<code class="inline-code">Configuration</code> instance.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_214">Differences between the RC2 and RC1 releases</h3>
<ul>
<li>
<p>Non backward compatible change!:
<code class="inline-code">FreemarkerServlet</code> now uses the encoding of
the template file for the output, unless you specify the
encoding in the <code class="inline-code">ContentType</code> init-param,
such as <code class="inline-code">text/html; charset=UTF-8</code>.</p>
</li>
<li>
<p>Non backward compatible change compared to RC1!: The
<code class="inline-code">capture_output</code> transform creates variable
in the current namespace (as <code class="inline-code">assign</code>
directive) with the <code class="inline-code">var</code> parameter, not a
global variable.</p>
</li>
<li>
<p>The new and preferred way of number formatting with
<code class="inline-code">string</code> built-in is
<code class="inline-code">foo?string(format)</code>, instead of the less
natural <code class="inline-code">foo?string[format]</code>.</p>
</li>
<li>
<p>The <code class="inline-code">string</code> built-in works for boolean
values. For example: <code class="inline-code">${spamFilter?string(&quot;enabled&quot;,
&quot;disabled&quot;)}</code>. For more information <a href="ref_builtins_boolean.html#ref_builtin_string_for_boolean">read the
reference</a>.</p>
</li>
<li>
<p>The default strings for outputting boolean value using
the <code class="inline-code">string</code> built-in can be set using the
<code class="inline-code">boolean_format</code> setting.</p>
</li>
<li>
<p>String literals can be quoted with apostrophe-quote.
<code class="inline-code">&quot;foo&quot;</code> and <code class="inline-code">&#39;foo&#39;</code> are
equivalent.</p>
</li>
<li>
<p>The new interface
<code class="inline-code">freemarker.cache.CacheStorage</code> allows users
to plug custom template caching strategies with the
<code class="inline-code">cache_storage</code> setting. The core package now
ships with two implementations:
<code class="inline-code">SoftCacheStorage</code> and
<code class="inline-code">StrongCacheStorage</code>. For more information
read: <a href="pgui_config_templateloading.html">Programmer&#39;s Guide/The Configuration/Template loading</a></p>
</li>
<li>
<p>You can set settings with string name and string value
with the new <code class="inline-code">setSetting(String key, String
value)</code> method of <code class="inline-code">Configurable</code>
super-classes (as <code class="inline-code">Configuration</code>).</p>
</li>
<li>
<p>Other new <code class="inline-code">Configuration</code> methods:
<code class="inline-code">getTemplateLoader</code>,
<code class="inline-code">clone</code>.</p>
</li>
<li>
<p><code class="inline-code">assign</code>, <code class="inline-code">local</code> and
<code class="inline-code">global</code> now can capture the output generated
be the nested template fragment into the variable. This
deprecates <code class="inline-code">capture_output</code> transform. More
information: <a href="ref_directive_assign.html#ref.directive.assign">assign
directive reference</a></p>
</li>
<li>
<p>Other new <code class="inline-code">Configuration</code> methods:
<code class="inline-code">getTemplateLoader</code>,
<code class="inline-code">clone</code>.</p>
</li>
<li>
<p>Changes to <code class="inline-code">TemplateTransformModel</code>
interface: <code class="inline-code">getWriter</code> can throw
<code class="inline-code">IOException</code>, and can return
<code class="inline-code">null</code> if the transform does not support body
content.</p>
</li>
<li>
<p>Till now
<code class="inline-code">TemplateTransformModel.getWriter</code> has
received null as parameter map if the transform was called
without parameters. From now, it will receive an empty Map
instead. Note that the previous API documentation didn&#39;t state
that it always receives null if there are no parameters, so
hopelessly only very few classes exploit this design
mistake.</p>
</li>
<li>
<p>Changes to <code class="inline-code">TemplateControl</code> interface:
<code class="inline-code">onStart</code> and <code class="inline-code">afterBody</code>
methods are now allowed to throw
<code class="inline-code">IOException</code>.</p>
</li>
<li>
<p>Path that contains <code class="inline-code">//:</code> is considered
as absolute path.</p>
</li>
<li>
<p>New <a href="ref_builtins_string.html">string
built-ins</a>: <code class="inline-code">index_of</code>,
<code class="inline-code">last_index_of</code>,
<code class="inline-code">starts_with</code>, <code class="inline-code">ends_with</code>,
<code class="inline-code">replace</code>, <code class="inline-code">split</code>,
<code class="inline-code">chop_linebreak</code>.</p>
</li>
<li>
<p>New <a href="ref_builtins_sequence.html">sequence
built-ins</a>: <code class="inline-code">sort</code>,
<code class="inline-code">sort_by</code>.</p>
</li>
<li>
<p>All <code class="inline-code">Configuration</code> level settings can
by set with Servlet init-params
(<code class="inline-code">template_exception_handler</code>,
<code class="inline-code">locale</code>, <code class="inline-code">number_format</code>,
etc.).</p>
</li>
<li>
<p>Bugfix: classes may were not found if they was available
only in the <code class="inline-code">WEB-INF</code>, and FreeMarker tried
to load the class dynamically.</p>
</li>
<li>
<p>Bugfix: <code class="inline-code">setLocalizedLookup(false)</code> of
<code class="inline-code">Configuration</code> was overridden when you have
called <code class="inline-code">setTemplateLoader</code>.</p>
</li>
<li>
<p>Bugfix: String concatenation had performance problem if
there was multiple concatenations chained, as:
<code class="inline-code">&quot;a&quot;+x+&quot;a&quot;+x+&quot;a&quot;+x+&quot;a&quot;+x+&quot;a&quot;+x</code>.</p>
</li>
<li>
<p>Bugfix: white-space stripping was not worked with tags
spanning over multiple lines.</p>
</li>
<li>
<p>Bugfix: Removing several dependencies on JDK 1.3, so
FreeMarker can be build for JDK 1.2.2.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_215">Differences between the Preview 2 and RC1 releases</h3>
<ul>
<li>
<p><code class="inline-code">ftl</code> is now stricter, and does not
allow custom parameters. To associate custom attributes to
templates, we may add a new directive later, if there is a
demand for it.</p>
</li>
<li>
<p><code class="inline-code">escape</code> directive does not affect
numerical interpolations
(<code class="inline-code">#{<em class="code-color">...</em>}</code>)
anymore, as it has caused errors with string escapes as
<code class="inline-code">?html</code>.</p>
</li>
<li>
<p>The <code class="inline-code">normalizeName</code> method of
<code class="inline-code">freemarker.cache.TemplateLoader</code> has been
removed, because it has caused too many complications.
Instead, normalization happens on a single point in the
<code class="inline-code">TempateCache</code>. In consequence, FreeMarker is
now stricter about the format of template paths, as things
like <code class="inline-code">/../</code> are interpreted by the
core.</p>
</li>
<li>
<p>Experimental feature: With the
<code class="inline-code">setSimpleMapWrapper</code> method of
<code class="inline-code">BeansWrapper</code> you can configure it to wrap
<code class="inline-code">java.util.Map</code>-s as
<code class="inline-code">TemplateHashModelEx</code>-s, and do not expose
the methods of the object.</p>
</li>
<li>
<p>New <code class="inline-code">Configuration</code> methods:
<code class="inline-code">set/getLocalizedLookup</code>,
<code class="inline-code">clearTemplateCache</code>,
<code class="inline-code">clearSharedVariables</code>.</p>
</li>
<li>
<p>More cleanups in the <code class="inline-code">Environment</code>
API.</p>
</li>
<li>
<p>Better JSP standard compliance: JSP page-scope variables
are the global variables that were created in the template
(not the variables of the data-model).</p>
</li>
<li>
<p>JDOM independent XML-wrapping:
<code class="inline-code">freemarker.ext.xml.NodeListModel</code> is a
re-implementation of
<code class="inline-code">freemarker.ext.jdom.NodeListModel</code> that does
not rely on JDOM; you don&#39;t need JDOM .jar anymore. The new
<code class="inline-code">NodeListModel</code> automatically uses W3C DOM,
dom4j, or JDOM, depending on which library is available (that
is, depending on what object do you pass to its
constructor).</p>
</li>
<li>
<p>Bugfix: <code class="inline-code">WebappTemplateLoader</code>:
Template updating didn&#39;t worked correctly with Tomcat due the
caching of resources. Now
<code class="inline-code">WebappTemplateLoader</code> tries to access the
resources directly as <code class="inline-code">File</code>, if it is
possible, thus bypasses the caching.</p>
</li>
<li>
<p>Bugfix: Templates loaded with
<code class="inline-code">MultiTemplateLoader</code> subclasses was removed
from the template cache after the template update delay has
elapsed (5 seconds by default) even if the template file was
unchanged. This can cause lot of extra load for a high-traffic
server if you have many templates or if the template update
delay was set to 0 second.</p>
</li>
<li>
<p>Bugfix: Undefined variables in hash and sequence
constructors (as <code class="inline-code">[a, b, c]</code>) didn&#39;t caused
errors.</p>
</li>
</ul>
<h3 class="content-header header-section3" id="autoid_216">Differences between the Preview 1 and Preview 2
releases</h3>
<ul>
<li>
<p>All 16-bit Unicode letters and numbers are allowed in
identifiers, as well as the <code class="inline-code">$</code> character (as
in Java programming language). Thus you can use accented
letters, Arabic letters, Chinese letters, etc. as identifiers
in templates</p>
</li>
<li>
<p>Macros now can create loop variables for the nested
content. For more information <a href="dgui_misc_userdefdir.html#dgui_misc_userdefdir_loopvar">read
this</a>.</p>
</li>
<li>
<p>New directives: <code class="inline-code">t</code>,
<code class="inline-code">rt</code> and <code class="inline-code">lt</code> directives
allow you to do explicit white-space removal in extreme FTL
applications. For more information read <a href="ref_directive_t.html#ref.directive.t">the reference</a>.</p>
</li>
<li>
<p>The syntax of assignment-with-namespace has changed from
<code class="inline-code">&lt;#assign foo=123 namespace=myLib&gt;</code>) to
<code class="inline-code">&lt;#assign foo=123 in myLib&gt;</code>, since the
previous syntax was confusing because its similarity to a
bulk-assignment.</p>
</li>
<li>
<p>Bulk assignments (as <code class="inline-code">&lt;#assign x=1, y=2,
z=3&gt;</code>) no longer need colon to separate the
assignments (as <code class="inline-code">&lt;#assign x=1 y=2
z=3&gt;</code>), although it is still allowed to preserve
backward compatibility.</p>
</li>
<li>
<p>Positional parameter passing is supported for macro
calls as shorthand form of normal named parameter passing. For
more details read <a href="ref_directive_userDefined.html#ref_directive_userDefined_positionalParam">read the
reference</a>.</p>
</li>
<li>
<p>New built-in, <code class="inline-code">namespace</code>, to get the
namespace of the currently executing macro.</p>
</li>
<li>
<p><code class="inline-code">TransformControl</code> interface (was
experimental earlier): If the <code class="inline-code">Writer</code>
returned by
<code class="inline-code">TemplateTransformModel.getWriter</code> implements
this interface, it can instruct the engine to skip or to
repeat evaluation of the nested content, and gets notified
about exceptions that are thrown during the nested content
evaluation. For more information please read the API
documentation.</p>
</li>
<li>
<p>Jython wrapper can now wrap arbitrary Java objects, not
only <code class="inline-code">PyObject</code>-s. If an object is passed to
the wrapper that is neither a
<code class="inline-code">TemplateModel</code>, nor a
<code class="inline-code">PyObject</code>, it is first coerced into a
<code class="inline-code">PyObject</code> using Jython&#39;s own wrapping
machinery, and then wrapped into a
<code class="inline-code">TemplateModel</code> as any other
<code class="inline-code">PyObject</code>.</p>
</li>
<li>
<p>Some cleanups in the <code class="inline-code">Environment</code>
API.</p>
</li>
<li>
<p>The Web application related examples has been
replaced.</p>
</li>
<li>
<p>Bugfix: Templates loaded with
<code class="inline-code">URLTemplateLoader</code> subclasses was removed
from the template cache after the template update delay has
elapsed (5 seconds by default) even if the template file was
unchanged. This can cause lot of extra load for a high-traffic
server if you have many templates or if the template update
delay was set to 0 second.</p>
</li>
<li>
<p>Bugfix: <code class="inline-code">FreeMarkerServlet</code> has thrown
<code class="inline-code">ServletException</code> even if a debug
<code class="inline-code">TemplateException</code> handler was in use (so
you may got Error 500 page instead of debug
information).</p>
</li>
</ul>
<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="versions_2_2_1.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_1_5.html"><span>Next</span></a></div></div></div></div> </div>
</div>
<div class="site-footer"><div class="site-width"><div class="footer-bottom"> <p class="last-generated">
Last generated:
<time itemprop="dateModified" datetime="2020-07-09T23:48:37Z" title="Thursday, July 9, 2020 11:48:37 PM GMT">2020-07-09 23:48:37 GMT</time> </p>
<p class="copyright">
© <span itemprop="copyrightYear">1999</span>–2020
<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
</div></div></div></body>
</html>