blob: 685715ef0ab20eb81cc91b45ca644a2b87560c2c [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.0 RC1 - 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.0 RC1">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="http://example.com/versions_2_0RC1.html">
<link rel="canonical" href="http://example.com/versions_2_0RC1.html">
<link rel="icon" href="favicon.png" type="image/png">
<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
</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_0RC1.html"><span itemprop="name">2.0 RC1</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><li><a href="api/index.html">API</a></li><li><a href="../index.html">Home</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 = ["FreeMarker Manual","Appendixes","Versions","2.0 RC1"];</script>
<script src="toc.js?1594338519184"></script>
<script src="docgen-resources/main.min.js?1594338519184"></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_0RC2.html"><span>Previous</span></a><a class="paging-arrow next" href="app_license.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="versions_2_0RC1" itemprop="headline">2.0 RC1</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#autoid_238" data-menu-target="autoid_238">Support for Numerical operations, both arithmetic and
boolean, as well as numerical ranges.</a></li><li><a class="page-menu-link" href="#autoid_239" data-menu-target="autoid_239">API Changes</a></li><li><a class="page-menu-link" href="#autoid_240" data-menu-target="autoid_240">Syntactical Miscellany</a></li></ul> </div><p>The first public release of FreeMarker 2.0 was on 18 March 2002.
Here is a summary of the changes in the Lazarus release, with respect
to the last stable release of FreeMarker Classic.</p><p><em>NOTA BENE</em>:</p><p>Despite the changes delineated above, the Lazarus release is
almost entirely backward-compatible with FreeMarker Classic. We
believe that <em>most</em> existing code and templates
that work under FreeMarker Classic will continue working under
Lazarus, with at most minimal changes. In practice, the most common
cases where legacy template code is broken will be where assumptions
were made about numbers and strings being equivalent. Note that in
FreeMarker 2, 2 + 2 does not result in &quot;22&quot;. The String &quot;1&quot; and the
number 1 are entirely different animals and thus, any code will be
broken if it relies on the boolean expression (&quot;1&quot;==1) being true.
There is a &quot;classic compatibility mode&quot; that can be set via:
<code class="inline-code">Template.setClassCompatibility()</code> that can be set so
that Lazarus emulates some of the quirky behavior of FreeMarker
Classic. However, any code that relied on the above &quot;features&quot; of
FreeMarker classic really should be reworked. You are less likely to
run into the other incompatibilities that are listed above. If you
come across any other anomalies, please do tell us about them.</p>
<h2 class="content-header header-section2" id="autoid_238">Support for Numerical operations, both arithmetic and
boolean, as well as numerical ranges.</h2>
<ul>
<li>
<p>Scalars can now be either strings or numbers. (In
FreeMarker Classic all scalars were strings.) The basic
operations allowed are addition, subtraction, multiplication,
division, and modulus using the <code class="inline-code">+</code>,
<code class="inline-code">-</code>, <code class="inline-code">*</code>,
<code class="inline-code">/</code>, and <code class="inline-code">%</code> operators
respectively. Arbitrary-precision arithmetic with integers and
floating point numbers are provided. Though our goal is
definitely to follow the principle of least surprise, for
backward compatibility, the <code class="inline-code">+</code> operator still
is used for string concatenation. If either the left hand side
or the right hand side of <code class="inline-code">lhs + rhs</code> is
non-numerical, we revert to interpreting this as string
concatenation. Thus, in FreeMarker 2, 2+2 evaluates to the
number 4, while any of &quot;2&quot;+2 or 2+&quot;2&quot; or &quot;2&quot;+&quot;2&quot; evaluate to the
string &quot;22&quot;. In FreeMarker Classic, rather embarrassingly, all
of the above, including 2+2, evaluated to the string &quot;22&quot;. An
attempt to use any other arithmetic operator besides the
<code class="inline-code">+</code> with non-numerical operands will cause an
exception to be thrown.</p>
</li>
<li>
<p>Output of a numerical expression can be made explicit via
the alternative <code class="inline-code">#{....}</code> syntax. If the
expression within the curly parentheses does not evaluate to a
numerical value, an exception is thrown. The older ${....}
syntax can evaluate to either a number or a string. In general,
if, for logical reasons, the output <em>must</em> be
numerical, it is preferable to use the #{...} syntax, since it
adds an extra sanity check. Note that if, by some miracle, the
character sequence &quot;#{&quot; occurs in your template, you will have
to use a workaround to prevent problems. (The &lt;noparse&gt;
directive is one possibility.)</p>
</li>
<li>
<p>In this release, there is a facility for specifying the
number of digits to show after the decimal point. The following
code specifies to show at least 3 digits after the decimal point
but not more than 6. This is optional. This option is only
available if you use the #{...} syntax.</p>
<div class="code-wrapper"><pre class="code-block code-template">#{foo + bar ; m3M6} </pre></div>
<p>(Note that the above is something of a stopgap measure.
Future releases will move toward supporting fully
internationalization and localization of number and currency
formatting.</p>
</li>
<li>
<p>Numerical expressions can be used in boolean expressions
via the comparison operators: <code class="inline-code">lt</code>,
<code class="inline-code">gt</code>, <code class="inline-code">lte</code>, and
<code class="inline-code">gte</code>. In the web space, where FreeMarker is
most used in practice, using the more natural operators such as
&lt; and &gt; would tend to confuse HTML-oriented editors. An
attempt to compare non-numerical expressions using these
operators leads to a <code class="inline-code">TemplateException</code> being
thrown. If, by some coincidence, you have variables named &quot;lt&quot;,
&quot;gt&quot;, &quot;lte&quot;, or &quot;gte&quot;, you will have to change their names,
since they are now keywords in the language.</p>
</li>
<li>
<p>Numerical ranges are supported.</p>
<div class="code-wrapper"><pre class="code-block code-template">&lt;#list 1990..2001 as year&gt;
blah blah in the year ${year} blah
&lt;/#list&gt; </pre></div>
<p>The left hand and right hand sides of the
<code class="inline-code">..</code> operator must be numerical, or an
exception is thrown. They also need not be literal numbers, but
can be more complex expressions that evaluate to a numerical
scalar value. Note that it is also possible to write a range
that descends in value:</p>
<div class="code-wrapper"><pre class="code-block code-template">&lt;#list 2001..1990 as year&gt;
blah blah in the year ${year} blah blah
&lt;/#list&gt; </pre></div>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_239">API Changes</h2>
<ul>
<li>
<p>The <code class="inline-code">TemplateNumberModel</code> interface and
the <code class="inline-code">SimpleNumber</code> implementation were added to
support exposing numerical values.</p>
</li>
<li>
<p>The <code class="inline-code">TemplateListModel</code> API in FreeMarker
Classic had some design problems -- particularly in terms of
supporting thread-safe code. It has been deprecated in favor of
the following API&#39;s: <code class="inline-code">TemplateCollectionModel</code>
and <code class="inline-code">TemplateSequenceModel</code>. The
<code class="inline-code">SimpleList</code> class was refactored to implement
the above interfaces (and paradoxically, does not implement the
TemplateListModel interface.) Code that uses the deprecated
<code class="inline-code">TemplateListModel</code> should be
refactored.</p>
</li>
<li>
<p>The Expose Package by Attila Szegedi has been made an
integral part of the FreeMarker distribution and is now under
the freemarker.ext.* hierarchy. This package provides advanced
models for representing arbitrary Java objects as template
models, for representing XML documents as template models, as
well as classes to facilitate the integration of FreeMarker with
servlets and Ant.</p>
</li>
<li>
<p>In FreeMarker Classic, there were some utility classes
such as <code class="inline-code">freemarker.template.utility.Addition</code>
etcetera that existed as workarounds for the lack of numerical
operations in FreeMarker. Those have been removed and will
probably not be missed.</p>
</li>
<li>
<p>In FreeMarker Classic, the <code class="inline-code">SimpleScalar</code>
object was mutable, it had a <code class="inline-code">setValue</code> method.
This was fairly obviously a design mistake. Any code that relied
on this must be refactored. Note that in this release, both
<code class="inline-code">SimpleScalar</code> and the newly introduced
<code class="inline-code">SimpleNumber</code> are both immutable and
final.</p>
</li>
</ul>
<h2 class="content-header header-section2" id="autoid_240">Syntactical Miscellany</h2>
<ul>
<li>
<p>The if-elseif-else syntax was introduced. FreeMarker
classic only had if-else. This construct should probably (in the
opinion of the author of this document -- Revusky) be used in
preference to switch-case since the switch-case with
fall-through is a notoriously error-prone construct for most
mortal men.</p>
</li>
<li>
<p>You can now do a multiple assignment in one
&lt;assign...&gt; directive. For example: <code class="inline-code">&lt;assign x
= 1, y = price*items, message=&quot;foo&quot;&gt;</code></p>
</li>
<li>
<p>A scalar will no longer be interpreted as a one-item list
in a &lt;list...&gt; or &lt;#foreach...&gt; block. If you have
code that relied on this feature, there is an easy workaround,
since you can simply define a list literal with exactly one
item.</p>
<div class="code-wrapper"><pre class="code-block code-template"> &lt;assign y=[x]&gt;
<strong>and then...</strong>
&lt;list y as item&gt;...&lt;/list&gt; </pre></div>
</li>
</ul>
<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="versions_2_0RC2.html"><span>Previous</span></a><a class="paging-arrow next" href="app_license.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><div class="col-right"><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="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 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>