Date of release: 2004-June-15
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.
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 XML Processing Guide for more details.
Non backward-compatible changes!
-
Since interpolations (
${...}and#{...}) now work inside string literals, the character sequence${and#{in string literals are reserved for that. So if you have something like<#set x = "${foo}">, then you have to replace it with<#set x = r"${foo}">-- beware, escapes such as\nwill not work in raw (r) strings. -
The default (initial) value of the
strict_syntaxsetting has been changed fromfalsetotrue. Whenstrict_syntaxistrue, tags with old syntax as<include "foo.ftl">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<#include "foo.ftl">, since only parts that starts with<#,</#,<@, or</@count as FTL tags. Or, to recover the old transitional behavior, where both legacy and new tag syntax was recognized, you have to explicitly setstrict_syntaxtofalse:cfg.setStrictSyntaxMode(false). Also, for individual templates you can force the old behavior by starting the template with<#ftl strict_syntax=false>. (For more information about why strict syntax is better than old syntax read this...) -
Several classes were moved from the
freemarker.templatepackage, to the newfreemarker.corepackage:-
"Normal" classes:
ArithmeticEngine,Configurable,Environment -
Exceptions:
InvalidReferenceException,NonBooleanException,NonNumericalException,NonStringException,ParseException,StopException -
Errors:
TokenMgrError
The main reason of the splitting of
freemarker.templatepackage was that the amount of "expert" public classes and interfaces grows too much, as we introduce API-s for third-party tools, such as debugging API. -
"Normal" classes:
-
freemarker.template.TemplateMethodModel.execnow returnsObjectinstead ofTemplateModel. -
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
<#include ...>or user-defined directive tag with empty directive syntax as<@myMacro/>(or its equivalents:<@myMacro></@myMacro>and<@myMacro></@>). 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: Template Author's Guide/Miscellaneous/White-space handling/White-space stripping -
The
functiondirective is now used for defining methods. You should replacefunctionwithmacroin your old templates. Note, however, that oldfunction-s will still work if you don't use thereturndirective in them, and you invoke them with the deprecated thecalldirective. -
The expressions
as,in, andusingare 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.varsspecial variable:.vars["in"]. -
The
?newbuilt-in, as it was implemented, was a security hole. Now, it only allows you to instantiate a java object that implements thefreemarker.template.TemplateModelinterface. If you want the functionality of the?newbuilt-in as it existed in prior versions, make available an instance of thefreemarker.template.utility.ObjectConstructorclass to your template. (For example:myDataModel.put("objConstructor", new ObjectConstructor());, and then in the template you can do this:<#assign aList = objConstructor("java.util.ArrayList", 100)>) -
Changes to the
FreemarkerServlet:-
The
FreemarkerServletusesObjectWrapper.DEFAULT_WRAPPERby default instead ofObjectWrapper.BEANS_WRAPPER. What this means is that, by default, objects of typejava.lang.String,java.lang.Number,java.util.List, andjava.util.Mapwill be wrapped asTemplateModelsvia the classesSimpleScalar,SimpleNumber,SimpleSequence, andSimpleHashrespectively. 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 wrapsorg.w3c.dom.Nodeobjects into instances offreemarker.ext.dom.NodeModel. -
The
FreemarkerServletbase implementation no longer deduces the locale used for templates withHttpRequest.getLocale(). Rather, it simply delegates to the new protected method,deduceLocale. The default implementation of this method simply returns the value of configuration thelocalesetting.
-
Changes on the FTL side
-
Interpolation in string literals. For convenience, interpolations are now supported in string literals. For example:
<@message "Hello ${user}!" />is the same as<@message "Hello " + user + "!" /> -
Raw string literals: In string literals prefixed with
r, interpolations and escape sequences will not be interpreted as special tokens. For example:r"\n${x}"will be simply interpreted as the character sequence'\','n','$','{','x','}', and not as line-feed and the value of thexvariable. -
Method variables can be defined in FTL, with the
functiondirective. -
Support for a variable number of macro parameters. If the last parameter in a macro declaration ends with
..., 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 newfunctiondirective as well. -
A new header parameter,
strip_text, that removes all top-level text from a template. This is useful for "include files" to suppress newlines that separate the macro definitions. Seeftldirective -
New special variable:
.vars. This is useful to read top-level variables with square bracket syntax, for example.vars["name-with-hyphens"]and.vars[dynamicName]. -
macroand assignment directives now accept arbitrary destination variable name with quoted syntax. For example:<#macro "name-with-hyphens">...or<#assign "foo bar" = 123>. -
The
?keysand?valueshash 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 sequence built-ins. (Note for the programmers: TheTemplateHashModelExinterface has not been changed. Your old code will work. See the API documentation to see why.) -
Existence built-ins (
?default,?exists, etc.) are now working with sequence sub variables as well. Read the documentation of thedefaultbuilt-in for more information. -
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
<#include ...>or user-defined directive tag with empty directive syntax as<@myMacro/>(or its equivalents:<@myMacro></@myMacro>and<@myMacro></@>). 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: Template Author's Guide/Miscellaneous/White-space handling/White-space stripping -
White-space stripping can be disabled for a single line with the
ntdirective (for No Trim). -
Hashes can be concatenated using the
+operator. The keys in the hash on the right-hand side take precedence. -
New built-ins for Java and JavaScript string escaping: j_string and js_string
-
The
replaceandsplitbuilt-ins now support case-insensitive comparsion and regular expressions (J2SE 1.4+ only), and some other new options. More information can be found here. -
New built-in for regular expression matching (J2SE 1.4+ only):
matches -
New built-in,
eval, to evaluate a string as FTL expression. For example"1+2"?evalreturns the number 3. -
New built-ins for Java and JavaScript string escaping: j_string and js_string
-
New special variables to read the value of the locale setting:
locale,lang. See more in the reference... -
New special variable to read the FreeMarker version number:
version. See more in the reference... -
Tree new directives,
recurse,visitandfallback, 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 chapter on declarative XML processing for more details. -
The
?newbuilt-in, as it was implemented, was a security hole. Now, it only allows you to instantiate a java object that implements thefreemarker.template.TemplateModelinterface. If you want the functionality of the?newbuilt-in as it existed in prior versions, make available an instance of thefreemarker.template.utility.ObjectConstructorclass to your template. (For example:myDataModel.put("objConstructor", new ObjectConstructor());, and then in the template you can do this:<#assign aList = objConstructor("java.util.ArrayList", 100)>) -
Variable names can contain
@anywhere (without using quote-bracket syntax). For example:<#assign x@@@ = 123>is valid. -
The expressions
as,in, andusingare now keywords in the template language and cannot be used as top-level variable names without square-bracket syntax (as.vars["in"]). -
New parameter to the
ftldirective:attributes. 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't try to understand the meaning of the attributes. It'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. -
Other minor quality improvements...
Changes on the Java side
-
Smarter default object wrapping: The default object wrapper is now
freemarker.template.DefaultObjectWrapper, which falls back on wrapping arbitrary objects as beans using thefreemarker.ext.beans.BeansWrapper. Also, it will wraporg.w3c.dom.Nodeobjects with the new DOM wrapper. Also, it is aware of Jython objects, and will usefreemarker.ext.jython.JythonWrapperif 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.) -
freemarker.template.TemplateMethodModel.execnow returnsObjectinstead ofTemplateModel. -
The default (initial) value of the
strict_syntaxsetting has been changed fromfalsetotrue. Whenstrict_syntaxistrue, tags with old syntax as<include "foo.ftl">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<#include "foo.ftl">, since only parts that starts with<#,</#,<@, or</@count as FTL tags. Or, to recover the old transitional behavior, where both legacy and new tag syntax was recognized, you have to explicitly setstrict_syntaxtofalse:cfg.setStrictSyntaxMode(false). Also, for individual templates you can force the old behavior by starting the template with<#ftl strict_syntax=false>. (For more information about why strict syntax is better than old syntax read this...) -
New
CacheStorageimplementation:freemarker.cache.MruCacheStorage. 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.freemarker.cache.SoftCachseStorageandStrongCachseStorageare deprected,MruCachseStorageis used everywhere instead. The default cache storage is now anMruCachseStorageobject with 0 strong size, and infinite soft size.Configuration.setSettingforcache_storagenow understands string values as"strong:200, soft:2000". -
For
BeansWrappergenerated models, you can now use the${obj.method(args)}syntax to invoke methods whose return type isvoid.voidmethods now returnTemplateModel.NOTHINGas their return value. -
freemarker.template.SimpleHashnow can wrap read-onlyMap-s, such as the map of HTTP request parameters in Servlet API. -
The
TemplateNodeModelinterface was introduced to support recursive processing of trees of nodes. Typically, this will be used in relation to XML. -
New package:
freemarker.ext.dom. This contains the new XML wrapper, that supports the processing of XML documents using the visitor pattern (i.e. with<#visit ...>and similar directives), and to provide more convenient XML traversing as the legacy wrapper. See the XML processing guide for more details. -
New package:
freemarker.core. Classes used by mostly power-users was moved here from thefreemarker.templatepackage. The main reason of the splitting offreemarker.templatepackage was that the amount of "expert" public classes and interfaces grows too much, as we introduce API-s for third-party tools, such as debugging API. -
New package:
freemarker.debug. 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 thefreemarker.debugpackage. -
You can query the FreeMarker version number with static method
Configuration.getVersionNumber(). Also, theManifest.mfincluded infreemarker.jarnow contains the FreeMarker version number, furthermore, executing it withjava -jar freemarker.jarwill print the version number to the stdout. -
Added a new protected
FreemarkerServletmethod:Configuration getConfiguration(). -
Date support is now labeled as final. (It was experimental earlier.)
-
The
BeansWrapperhas been improved to prevent some security exceptions when introspecting. -
Other minor quality improvements and extensions...
Other changes
-
Fixes and improvements in the Manual and in the API JavaDoc.
The history of the releases before the final version
Differences between the final release and Release Candidate 4
-
Added a new special variable to print the FreeMarker version number:
version. See more in the reference... -
Minor documentation fixes and improvements.
Differences between the Release Candidate 4 and Release Candidate 3
-
The
BeansWrapperhas been improved to prevent some security exceptions when introspecting. -
The
FreemarkerXmlTaskhas two new sub-tasks that can be used to prepare template execution with Jython scripts:prepareModelandprepareEnvironment. Thejythonsub-task is now deprecated, and does the same asprepareEnvironment. See the Java API documentation for more details. -
New special variable to read the FreeMarker version number:
version. See more in the reference... -
Bugfix: Greater-than sign doesn't confuse the
evalbuilt-in anymore. -
Bugfix: The
BeansWrappernow wrapps thenullreturn values of methods appropriately. -
Bugfix: The
FreemarkerXmlTaskdoesn't need Jython classes anymore, unless you really use Jython scripts. Several other bugfixes in the Jython related features. -
Bugfix: If the template exception handler has ignored the exception, errors occurring in interpolations inside FTL tags (e.g.
<#if "foo${badVar}" != "foobar">) 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<#if "foo"+badVar != "foobar">, which should be 100% equivalent with the previous example.) -
Bugfix: The
FileTemplateLoaderis now more robust when it receives paths that are malformed according the native file system. In the earlier version such paths sometimes caused unexpectedIOExceptionthat aborted the searching for the template in furtherFileTemplateLoader-s when you use theMultiTemplateLoader.
Differences between the Release Candidate 3 and Release Candidate 2
-
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.
Differences between the Release Candidate 2 and Release Candidate 1
-
Bugfix: The template cache didn't reload the template when it was replaced with an older version.
-
API JavaDoc fix: date/time related classes/interfaces were marked as experimental. They are not experimental.
-
Minor site improvements.
Differences between the Release Candidate 1 and Preview 16 releases
-
Warning! Non-backward-compatible change! The default (initial) value of the
strict_syntaxsetting has been changed fromfalsetotrue. Whenstrict_syntaxistrue, tags with old syntax as<include "foo.ftl">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<#include "foo.ftl">, since only parts that starts with<#,</#,<@, or</@count as FTL tags. Or, to recover the old transitional behavior, where both legacy and new tag syntax was recognized, you have to explicitly setstrict_syntaxtofalse:cfg.setStrictSyntaxMode(false). Also, for individual templates you can force the old behavior by starting the template with<#ftl strict_syntax=false>. (For more information about why strict syntax is better than old syntax read this...) -
New parameter to the
ftldirective:attributes. 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't try to understand the meaning of the attributes. It'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. -
Bugfix:
freemarker.template.utility.DeepUnwrapunwrapped sequences to emptyArrayList-s. -
Bugfix: If you included/imported a template with
*/in path (acquisition), and that template in turn itself included/imported another template with*/in path, it may failed. -
New methods to the
freemarker.core.Environment:importLib(Template loadedTemplate, java.lang.String namespace),getTemplateForImporting(...),getTemplateForInclusion(...). -
Improvements in the
java.io.IOExceptionrelated error messages of theincludeandimportdirectives. -
Minor improvements in the documentation.
Differences between the Preview 16 and Preview 15 releases
-
New package:
freemarker.debug. 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 thefreemarker.debugpackage. (The debugging API is present for a while, just I forgot to announce it in the version history. Sorry for that.) -
Bugfix: With the new XML wrapper,
@@markupand similar special keys:-
have returned
<foo></foo>for empty elements instead of<foo />. Other than it was needlessly verbose, it has confused browsers if you generate HTML. -
have showed the attributes that have no explicitly given value in the original document, just a default value coming form the DTD.
-
have forgot to put space before the system identifier in the
<!DOCTYPE ...>.
-
-
Bugfix: XPath with Jaxen has died with
NullPointerExceptionif the context was an empty node set. -
A bit more intelligent Xalan XPath error messages.
-
Revoked fallback-to-classloader logic from the template cache.
-
From now on, if no XPath engine is available, and the hash key in an XML query can't be interpreted without XPath, an error will tell this clearly, rather than silently returning undefined variable (null).
-
Bugfix: Some templates have caused the parser to die.
-
Some other minor improvements here and there...
Differences between the Preview 15 and Preview 14 releases
-
Bugfix: The new default template cache storage (
MruCacheStorage) has started to continually fail withNullPointerExceptionfrom a random point of time, usually when the memory usage was high in the JVM. -
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.
Differences between the Preview 14 and Preview 13 releases
-
freemarker.template.TemplateMethodModel.execnow returnsObjectinstead ofTemplateModel. -
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.
doc["book/chapter[title=$currentTitle]"]). -
freemarker.cache.SoftCachseStorageandStrongCachseStorageis deprected. The more flexibleMruCachseStorageis used instead everywhere. The default cache storage is now anMruCachseStorageobject with 0 strong size, and infinite soft size.Configuration.setSettingforcache_storagenow understands string values as"strong:200, soft:2000". -
Bugfix:
freemarker.cache.MruCachseStoragehas died withClassCastExceptionsometimes. -
New built-ins for Java and JavaScript string escaping: j_string and js_string
-
freemarker.template.TemplateExceptionHandler.HTML_DEBUG_HANDLERnow prints more HTML-context-proof messages. -
You can query the FreeMarker version number with static method
Configuration.getVersionNumber(). Also, theManifest.mfincluded infreemarker.jarnow contains the FreeMarker version number, furthermore, executing it withjava -jar freemarker.jarwill print the version number to the stdout. -
Added a new protected
FreemarkerServletmethod:Configuration getConfiguration(). -
Bugfix: FreeMarker has frozen on empty conditional blocks in certain contexts.
-
Bugfix: Methods called twice on an object using the
listdirective, asparent.getChildren()with<#list parent.children as child> ...</#list>
Differences between the Preview 13 and Preview 12 releases
-
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
<#include ...>or user-defined directive tag with empty directive syntax as<@myMacro/>(or its equivalents:<@myMacro></@myMacro>and<@myMacro></@>). 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: Template Author's Guide/Miscellaneous/White-space handling/White-space stripping -
White-space stripping can be disabled for a single line with the
ntdirective (for No Trim). -
A new directive for the declarative XML processing:
fallback -
freemarker.template.SimpleHashnow can wrap read-onlyMap-s, such as the map of HTTP request parameters in Servlet API.
Differences between the Preview 12 and Preview 11 releases
The only change between this and the previous preview release is that Preview 11 had a bug where DOM trees would never be garbage-collected.
Differences between the Preview 11 and Preview 10 releases
-
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: XML Processing Guide
-
Attention! Attribute queries such as
foo.@barnow 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${foo.@bar}, but built-ins such as?exists,?if_existsor?defaultdon't work as before. For example, instead offoo.@bar?default('black'), you now have to writefoo.@bar[0]?default('black'). So if you have used existence built-ins with attributes, you have to find those occurrences in the templates and add that[0]. -
Attention! XML name-space handling has been totally reworked and is absolutely incompatible with pre 10. Don't worry about this if none of your XML input documents use you use
xmlnsattributes. Worry, though, if you have utilized the "loose mode", where only the local name of elements were compared, because that's now gone. Sorry... -
Attention! Special-keys
@@and@*now return a sequence of attribute nodes instead of the hash of them. -
Several hash keys are now working for node sequences that store multiple nodes. For example, to get the list of all
paraelements of allchapter-s, just writedoc.book.chapter.para. Or, to get list of title attributes of allchapter-s writedoc.book.chapter.@title. -
New special hash keys:
**,@@start_tag,@@end_tag,@@attribute_markup,@@text,@@qname. -
?parentfor attribute nodes now returns the element node the attribute node belongs to. -
You can use Jaxen instead of Xalan for XPath expressions, if you call the static
freemarker.ext.dom.NodeModel.useJaxenXPathSupport()method once. We plan to use Jaxen automatically instead of Xalan if it is available, just the Jaxen support is not fully functional yet.
-
-
New special variable:
.vars. This is useful to read top-level variables with square bracket syntax, for example.vars["name-with-hyphens"]and.vars[dynamicName]. -
New built-in,
eval, to evaluate a string as FTL expression. For example"1+2"?evalreturns the number 3. -
FreemarkerServletnow uses the configuration'slocalesetting, rather thanLocale.getDefault(), to set the locale of the templates. Also, the signature of thededuceLocalemethod has been changed. -
We have a new (beta status)
CacheStorageimplementation:freemarker.cache.MruCacheStorage. 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 withcfg.setCacheStorage(new freemarker.cache.MruCacheStorage(maxStrongSize, maxSoftSize)).
Differences between the Preview 10 and Preview 9 releases
-
The special key
@@xmlnswas removed in favor of a new FTL directive for the same purpose,<#xmlns...>. -
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
<#xmlns...>directive, but prefixes declared in the input XML doc will actually work with no declaration. -
Introduced a new special key called
@@textthat returns all the text nodes contained (recursively) in an element all concatenated together. -
Either Jaxen or Xalan can be used to provide XPath functionality. Prior versions only worked with Xalan.
-
The
FreemarkerServletusesObjectWrapper.DEFAULT_WRAPPERby default instead ofObjectWrapper.BEANS_WRAPPER. What this means is that, by default, objects of typejava.lang.String,java.lang.Number,java.util.List, andjava.util.Mapwill be wrapped asTemplateModelsvia the classesSimpleScalar,SimpleNumber,SimpleSequence, andSimpleHashrespectively. 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 wrapsorg.w3c.dom.Nodeobjects into instances offreemarker.ext.dom.NodeModel. -
The
FreemarkerServletbase implementation no longer deduces the locale to use from the HttpRequest.getLocale() hook. Rather, it simply delegates to adeduceLocale()hook that is overridable in subclasses. The base implementation simply usesLocale.getDefault()
Differences between the Preview 9 and Preview 8 releases
-
Fixed bugs introduced with Preview 8: XPath,
@@markupand@@nested_markupnow works with the document node.
Differences between the Preview 8 and Preview 7 releases
-
macroand assignment directives now accept arbitrary destination variable name with quoted syntax. For example:<#macro "foo-bar">...or<#assign "this+that" = 123>. 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. -
Special key
@@contentwas renamed to@@nested_markup. -
Fixed outdated XML related Manual parts (that were outdated even in Preview 7).
-
Better parse-error messages.
-
Minor bugfixes here and there...
Differences between the Preview 7 and Preview 6 releases
-
Caching of XPath queries should lead to significant performance improvements for XML processing, at least when XPath is heavily used.
-
Refinements in handling of XML namespaces in the XML processing functionality. The new
strict_namespace_handlingsetting introduced in 2.3pre6 was removed. A general-purpose solution was arrived at that should make that configuration setting unnecessary. -
Special key
@xmlnswas renamed to @@xmlns. Reserved namespace prefixdefaultwas renamed to@@default. -
The
ftldirective now accepts non-string types. -
New special keys were introduced for XML node wrappers in the freemarker.ext.dom package. The
@@markupkey returns the literal markup that make up that element and the@@contentkey returns all the element's markup excluding the opening and closing tags. -
Minor bugfixes here and there...
Differences between the Preview 6 and Preview 5 releases
-
Existence built-ins (
?default,?exists, etc.) now work with sequence sub variables as well. Read the documentation of thedefaultbuilt-in for more information. -
The
matchesbuilt-in now returns a sequence instead of a collection. -
Refinements in handling of XML namespaces in the XML processing functionality. A new setting,
strict_namespace_handlingwas 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. -
Minor bugfixes here and there...
Differences between the Preview 5 and Preview 4 releases
-
The
replaceandsplitbuilt-ins now support case-insensitive comparison and regular expressions (J2SE 1.4+ only), and some other new options. More information can be found here. -
New butilt-in for regular expression matching (J2SE 1.4+ only):
matches -
Minor bugfixes here and there...
-
Manual: More browser-safe HTML-s. More updated content.
Differences between the Preview 4 and Preview 3 releases
-
Bugfix: with multi-type variables,
+operator overload for hash type had higher precedence than the precedence of some older overloads. -
The API documentation was missing from the distribution
tar.gz.
Differences between the Preview 3 and Preview 2 releases
-
XML processing: Many various bugfixes, especially with the declarative processing.
-
XML processing: the
namespace_uribuilt-in, thexmlnsuriheader parameter, and theTemplateNodeModel.getNodeNamespacemethod were renamed tonode_namespaceandgetNodeNamespacerespectively. -
XML processing: Better documentation. Especially, note: XML Processing Guide
-
A new header parameter,
strip_text, that removes all top-level text from a template. Seeftldirective -
Support for a variable number of macro parameters. If the last parameter in a macro declaration ends with
..., 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. -
For
BeansWrappergenerated models, you can now use the${obj.method(args)}syntax to invoke methods whose return type isvoid.voidmethods now returnTemplateModel.NOTHINGas their return value.
Differences between the Preview 2 and Preview 1 releases
-
The
freemarker.ext.dom.NodeModelAPI changed slightly. ThesetDocumentBuilder()method was changed tosetDocumentBuilderFactory()because the older scheme was not thread-safe. ThestripCommentsandstripPIsmethods are renamed to TheremoveCommentsandremovePIs, and are fixed now. A new method,simplifyhas been added. -
The expressions
as,in, andusingare now keywords in the template language and cannot be used as top-level variable names without square-bracket syntax (as.vars["in"]). 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. -
The
?newbuilt-in, as it was implemented, was a security hole. Now, it only allows you to instantiate a java object that implements thefreemarker.template.TemplateModelinterface. If you want the functionality of the?newbuilt-in as it existed in prior versions, make available an instance of the newfreemarker.template.utility.ObjectConstructorclass to your template. -
The
<#recurse>directive was broken. It did not work with ausingclause. This is now fixed.
