Date of release: 2002-10-17
Templates and the Java API are not fully
compatible with 2.0 releases. You will need to revisit existing code
and templates, or use 2.1 for new projects only. Sorry for this
inconvenience; FreeMarker has undergone some revolutionary changes
since the 1.x series. We hope things will soon be sufficiently mature
for us to offer (almost) backward-compatible releases. Note that there
is a backward-compatibility flag that can be set via
Configuration.setClassicCompatible(true)
that
causes the new FreeMarker to emulate most of FreeMarker 1.x's
quirks.
Changes in FTL (FreeMarker Template Language)
-
More strict, reveals accidental mistakes in the templates, prevents showing incorrect information when something went wrong:
-
An attempt to access an undefined variable causes an error and aborts template processing (by default at least; see later). In earlier versions undefined variables were silently treated as empty (zero-length) strings. However, you can handle undefined variables in the template with some new built-ins. For example,
${foo?if_exists}
is equivalent with the${foo}
of earlier versions. Another way of looking at this is that null values no longer exist from the viewpoint of a template designer. Anything referenced must be a defined variable.Note however that the programmer can configure FreeMarker so that it ignores certain errors (say, undefined variables), and continues template processing by skipping the problematic part. This "loose" policy should be used only for sites that don't show critical information.
-
New variable type: boolean. Conditions in
if
/elseif
and operands of logical operators (&&
,||
,!
) must be booleans. Empty strings are no longer treated as a logical false.
-
-
Local and global variables. More info: Template Author's Guide/Miscellaneous/Defining variables in the template
-
Local variables for macros. You can create/replace local variables in macro definition bodies with the
local
directive -
You can create/replace global (non-local) variables with the
global
directive
-
-
The
include
directive now by default treats the passed filename as being relative to the including template's path. To specify absolute template paths, you now have to prepend them with a slash. -
The
include
directive can now use the acquisition algorithm (familiar from the Zope system) to look up the template to include. Basically, if a template is not found where it is looked up first, it is looked up in parent directories. This is however not a default behavior, rather it is triggered by a new syntactic element. -
Strict syntax mode: Allows you to generate arbitrary SGML (XML) without worrying about clashes with FreeMarker directives. For more information read: Template Language Reference/Deprecated FTL constructs/Old FTL syntax
-
Terse comments: you can use
<#-- ... -->
instead of<comment>...</comment>
-
Directive that you can use to change the locale (and other settings) inside the template:
setting
-
Directive to explicitly flush the output buffer:
flush
-
The top-level (root) hash is available via the variable
root
, which is now a reserved name. -
The misnamed
function
directive has been renamed tomacro
. -
String literals support various new escape sequences, including UNICODE escapes (
\xCODE
) -
The
compress
directive is now more conservative in removing line breaks. -
Built-in to capitalize the first word:
cap_first
-
Built-in to generate on-the-fly templates:
interpret
-
stop
directive has an optional parameter to describe the reason of termination -
Better error messages.
-
New variable type: date. Date support is experimental. It can change substantially in the future. Keep this in mind if you use it.
Changes on the Java side
-
ObjectWrapper
: You can put non-TemplateModel
objects directly into hashes, sequences and collections, and they will be automatically wrapped with the appropriateTemplateModel
implementation. The API of objects that are exposed to templates (SimpleXXX
) has been changed according to this, for example inSimpleHash
the oldput(String key, TemplateModel value)
is nowput(String key, Object object)
. Also, you can pass any kind of object as data-model toTemplate.process
. The alternative reflection basedObjectWrapper
can expose the members of any Java object automatically for the designer. More information: Object wrapping, Bean wrapper, Jython wrapper. -
The
Configuration
object was introduced as a central point to hold all your FreeMarker-related global settings, as well as commonly used variables that you want to have available from any template. Also it encapsulates the template cache and can be used to load templates. For more information read Programmer's Guide/The Configuration. -
TemplateLoader
: pluggable template loader, separates caching from template loading -
TemplateNumberModel
-s do not control their formatting anymore. They just store the data (i.e. a number). Number formatting is done by the FreeMarker core based on thelocale
andnumber_format
settings. This logic applies to the new experimental date type as well. -
TemplateBooleanModel
introduced: Only objects that implements this interface can be used as a boolean in true/false conditions. More info: Programmer's Guide/The Data Model/Scalars -
TemplateDateModel
introduced: objects that implements this interface are recognized as dates and can be locale-sensitively formatted. Date support is experimental in FreeMarker 2.1. It can change substantially in the future. Keep this in mind if you use it. -
The
TemplateModelRoot
interface was deprecated. As of FreeMarker 2.1, you can simply use any instance ofTemplateHashModel
instead. This actually is due to a significant architectural change. Variables set or defined in a template are stored in a separateEnvironment
object that only exists while the template is being rendered. Thus, the template doesn't modify the root hash. -
Changes to transformations
-
Completely rewritten
TemplateTransformModel
interface. More flexible, and does not impose output holding. More information: Programmer's Guide/The Data Model/Directives -
The
transform
directive now takes an optional set of key/value pairs.<transform myTransform; key1=value1, key2=value2 ...>
. More information:transform
directive -
The transforms that ship with the FreeMarker core are now available by default to all templates - i.e.
<transform html_escape>
will invoke thefreemarker.template.utility.HtmlEscape
transform. More information: Programmer's Guide/The Configuration/Shared variables
-
-
User-defined
TemplateModel
objects now can access the runtime environment (read and set variables, get the current locale, etc.) using anEnvironment
instance, which can be obtained by the staticEnvironment.getCurrentEnvironment()
method. As a result,TemplateScalarModel.getAsString
has been changed: it has no locale parameter. -
TemplateExceptionHandler
-s make it possible to define your own rules on what to do when a runtime error occurs (e.g. accessing a non existing variable) during template processing. For example, you can abort template processing (recommended for most sites), or skip the problematic statement and continue template processing (similar to old behavior). DebugMode has been removed, useTemplateExceptionHandler.DEBUG_HANDLER
orHTML_DEBUG_HANDLER
instead. -
Logging: FreeMarker logs certain events (runtime errors for example). For more information read Programmer's Guide/Miscellaneous/Logging.
-
SimpleIterator
was removed, but we provide aTemplateCollectionModel
implementation:SimpleCollection
. -
Arithmetic engine is pluggable (
Configuration.setArithmeticEngine
). The core distribution comes with two engines:ArithmeticEngine.BIGDECIMAL_ENGINE
(the default) that converts all numbers toBigDecimal
and then operates on them, andArithmeticEngine.CONSERVATIVE_ENGINE
that uses (more-or-less) the widening conversions of Java language, instead of converting everything toBigDecimal
. -
Changes to
freemarker.ext.beans
package: The JavaBeans adapter layer has suffered several major changes. First,BeansWrapper
is no longer a static utility class - you can now create instances of it, and every instance can have its own instance caching policy and security settings. These security settings are also new - you can now create JavaBeans wrappers that hide methods that are considered unsafe or inappropriate in a templating environment. By default, you can no longer call methods likeSystem.exit()
from the template (although you can manually turn off these safeguards). TheStaticModel
andStaticModels
classes are gone; their functionality is now replaced with theBeansWrapper.getStaticModels()
method. -
freemarker.ext.jython
package: FreeMarker can now directly use Jython objects as data-models using the Jython wrapper. -
Changes to
freemarker.ext.jdom
package: The package now uses the Jaxen package instead of its predecessor, the werken.xpath package to evaluate XPath expressions. Since Jaxen is a successor to werken.xpath, this can be considered to be an upgrade. As a consequence, namespace prefixes are now recognized in XPath expressions and the overall XPath conformance is better. -
Better error reporting: If the processing of a template is aborted by a
TemplateException
being thrown, or using a<#stop>
directive, FreeMarker will now output an execution trace with line and column numbers relative to the template source. -
The output is written to a simple
Writer
; no morePrintWriter
. This redesign causes FreeMarker to no longer swallowIOException
s during template processing. -
Various API cleanups, primarily the removing of superfluous constructor and method overloads.
Other changes
-
Documentation has been rewritten from scratch
Differences between the RC1 and final release
-
Added the support for date models and locale-sensitive date formatting. Date support is experimental in FreeMarker 2.1. It can change substantially in the future. Keep this in mind if you use it.
-
Added the
default
built-in which makes it possible to specify default values for undefined expressions. -
SimpleIterator
has been removed,SimpleCollection
has been introduced -
Arithmetic engine is pluggable. The core now contains two arithmetic engines:
ArithmeticEngine.BIGDECIMAL_ENGINE
andArithmeticEngine.CONSERVATIVE_ENGINE
. -
BeansWrapper
supports a new exposure level:EXPOSE_NOTHING
-
Constants
interface was removed...._WRAPPER
constants have been moved fromConstants
toObjectWrapper
,EMPTY_STRING
constant was moved toTemplateScalarModel
,NOTHING
constant was moved toTemplateModel
,TRUE
andFALSE
constants were moved toTemplateBooleanModel
. -
JAVABEANS_WRAPPER
was renamed toBEANS_WRAPPER
-
Configuration.get
andput
,putAll
were renamed togetSharedVariable
andsetSharedVariable
,setAllSharedVariables
-
Configuration.getClassicCompatibility
,setClassicCompatibility
were renamed toisClassicCompatible
,setClassicCompatible
-
Template.process
method overloads withuseReflection
parameter was removed. But now we havesetObjectWrapper
method in theConfiguration
, so you can set the preferred root-object wrapper there. -
Some superfluous method overloads were removed; these changes are backward compatible with RC1
-
Various minor JavaDoc and Manual improvements
-
Bugfix:
include
directive has calculated the base path of relative paths wrongly -
Bugfix: We have accidentally used a J2SE 1.3 class, but FreeMarker 2.1 must able to run on J2SE 1.2