Date of release: 2015-07-05
Changes on the FTL side
#list) has received some specialized convenience features that target typical tasks people do again and again in templates.
listdirective child directives. There are
itemsto deal with special cases with 0-length lists, and
sepfor inserting separators between items. For more details, see the
listdirective in the Reference.
New built-ins that act on loop variables:
Added convenience assignment operators, which can be used in assignment directives (
--: For example,
<#assign counter++>is equivalent to
<#assign counter = counter + 1>.
%=: For example,
<#assign counter += 2>is equivalent to
<#assign counter = counter + 2>.
thenbuilt-in, which can be used like a ternary operator:
someBoolean?then(whenTrue, whenFalse). Just like with the ternary operator of most other languages, only one of the parameter expressions will be evaluated. More details...
switchbuilt-in, which can be used like an in-line (expression) switch-case-default statement:
someValue?switch(case1, result1, case2, result2, ... caseN, resultN, defaultResult), where
defaultResultcan be omitted (then it will be error if none of the cases matches). More details...
Added camel case support for the identifiers that are part of the template language (user defined names aren't affected). For example, now
<#ftl stripText=true>are valid. However, within the same template, FreeMarker will require you to use the same naming convention consistently for all identifiers that are part of the template language. It's also possible to enforce the same naming convention on all templates from Java via
Configuration.setNamingConvention(int). It's certain that camel case will be the recommended convention starting from some future version, because the Java API-s users call from templates use that too.
Added new special variables,
.main_template_name. These deprecate
.template_name, which was always broken when it comes to macro calls. The new
.current_template_namealways returns the name of the template that contains the reference to the special variable, and
.main_template_namealways returns the name of the topmost template.
Smaller error message improvements. Like, added tip in the error message for the frequent issue when
someMapis not a sequence nor is coercible to string.
Bug fixed, activated with setting
incompatible_improvementsto 2.3.23: There's a long existing parse-time rule that says that
#break, in the FTL source code itself, must occur nested inside a breakable directive, such as
#switch. This check could be circumvented with
#function, like this:
<#list 1..1 as x><#macro callMeLater><#break></#macro></#list><@callMeLater />. After activating this fix, this will be caught as parse time error.
Changes on the Java side
Configuration.setNamingConvention(int). By default FreeMarker will auto-detect the naming convention (legacy VS camel case) used for the identifiers that are part of the template language, for each template independently. This setting lets you enforce a naming convention instead.
Configuration(and in fact any
Configurable) setting names now can be written with camel case as well. For example, if you are configuring FreeMarker from properties file, you can have
default_encoding=utf-8. You can use the two naming conventions (camel case, and tradition snake case) mixed, and
Configuration.setNamingConvention(int)does not influence this behavior.
Configuration.getTemplateUpdateDelayMilliseconds(). This deprecates
setTemplateUpdateDelay(int), which uses seconds resolution, hence going against Java conventions and often leading to misunderstandings. (Also that couldn't have a getter pair.)
template_update_delaysetting, when specified as a string (as inside
java.util.Properties), supports time units, like in
Environment.getCurrentTemplate()method, which return the currently executed template (as opposed to the main template).
WebappTemplateLoader.setAttemptFileAccess(boolean), which can be used to disable the legacy trick where we try to load templates through direct file access, so that template updating works without restarting. Disabling URL connection caches (
someURLBasedTemplateLoader.setURLConnectionUsesCaches(false), which is also the default since
incompatible_improvements2.3.21) probably solves that on modern Servlet containers.
TemplatePathinit-param, paths (like
/templates) can have a
?settings(...)postfix, with which you can set the JavaBean properties of the resulting
TemplateLoader. For example:
FileTemplateLoader.setEmulateCaseSensitiveFileSystem(boolean). This is handy when you are developing on Windows but will deploy to a platform with case sensitive file system. The default is
trueis only meant for development, not for production installations. The default can be overridden by setting the
org.freemarker.emulateCaseSensitiveFileSystemsystem property to
Bug fixed :
WebappTemplateLoaderdidn't find templates that are stored in
WEB-INF/lib/*.jar/META-INF/resources. Files under that directory are visible as
ServletContextresources since Servlet 3.0, yet
WebappTemplateLoaderhas usually failed to see them because of some internal tricks.
Bug fixed: If a template "file" was successfully opened for reading, but then there was an
IOExceptionduring reading its content, the parser (JavaCC) acted like if the template "file" was ended there, and the exception was suppressed. It's actually a JavaCC quirk that affects many other JavaCC-based languages too, but now FreeMarker has added a workaround in the
Templateconstructor, and so now an exception will be thrown as expected.
InvalidReferenceException.FAST_INSTANCEcould accidentally store reference to an
Environmentinstance, which hence was never garbage collected.
Bug fixed : When setting
incompatible_improvementsto 2.3.22, the special variable reference
.template_namein templates always returns the name of the main (topmost) template, due to an oversight in 2.3.22. Setting
incompatible_improvementsto 2.3.23 restores the old, backward compatible behavior. (Note that the old behavior that we emulate is itself broken, as it doesn't work well with macro calls; you should use
Bug fixed : Template parsing was abnormally slow for templates with very high number AST (abstract syntax tree) nodes on the same hierarchy level.
Bug fixed: When the template was concurrently replaced on the backing store during its first loading was still ongoing, the older version of the template could get into the cache with the time stamp of the new version, hence it wasn't reloaded after the configured update delay.
Bug fixed: The
log_template_exceptionssetting (added in 2.3.22) couldn't be set through the
$(hence generating an illegal escape) and haven't escaped
#. While this function is only used for generating error messages by FreeMarker, it's a public methods so anyone could use it.
Bugs fixed: Various canonical form glitches (they only affect error messages as far as FreeMarker is concerned).
Modernized Manual and site design with improved functionality (always visible navigation tree, search inside the Manual, etc.), thanks to Evangelia Dendramis. (Also now the Site uses the same format and HTML generator as the Manual.)
Many smaller Manual and site content updates/improvements.
Changes compared to 2.3.23 RC1:
.main_template_nameis now missing (
null) instead of
""if the template has no name
Some minor error message improvements