Date of release: 2015-07-05
Changes on the FTL side
-
Listing (
#list) has received some specialized convenience features that target typical tasks people do again and again in templates.-
New
listdirective child directives. There areelseanditemsto deal with special cases with 0-length lists, andsepfor inserting separators between items. For more details, see thelistdirective in the Reference. -
New built-ins that act on loop variables:
var?index(deprecatesvar_index),var?counter(1-based index),var?has_next(deprecatesvar_has_next),var?is_first,var?is_last,var?item_parity(returns"odd"or"even"),var?item_parity_cap,var?item_cycle(...), etc.
-
-
Added convenience assignment operators, which can be used in assignment directives (
#assign,#globaland#localcurrently) only:-
++and--: For example,<#assign counter++>is equivalent to<#assign counter = counter + 1>. -
+=,-=,*=,/=and%=: For example,<#assign counter += 2>is equivalent to<#assign counter = counter + 2>.
-
-
Added the
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... -
Added the
switchbuilt-in, which can be used like an in-line (expression) switch-case-default statement:someValue?switch(case1, result1, case2, result2, ... caseN, resultN, defaultResult), wheredefaultResultcan 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
<#noEscape>${x?upperCase}</#noEscape>or<#setting numberFormat="0.0">or<#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 viaConfiguration.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,
.current_template_nameand.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
someMap[someNumber]complains thatsomeMapis 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#listor#switch. This check could be circumvented with#macroor#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
-
Added
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 anyConfigurable) setting names now can be written with camel case as well. For example, if you are configuring FreeMarker from properties file, you can havedefaultEncoding=utf-8instead ofdefault_encoding=utf-8. You can use the two naming conventions (camel case, and tradition snake case) mixed, andConfiguration.setNamingConvention(int)does not influence this behavior. -
Added
Configuration.setTemplateUpdateDelayMilliseconds(long)andConfiguration.getTemplateUpdateDelayMilliseconds(). This deprecatessetTemplateUpdateDelay(int), which uses seconds resolution, hence going against Java conventions and often leading to misunderstandings. (Also that couldn't have a getter pair.) -
The
template_update_delaysetting, when specified as a string (as insidejava.util.Properties), supports time units, like intemplate_update_delay=500 ms. -
Added
Environment.getCurrentTemplate()method, which return the currently executed template (as opposed to the main template). -
Added
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 sinceincompatible_improvements2.3.21) probably solves that on modern Servlet containers. -
In the
FreemarkerServletTemplatePathinit-param, paths (like/templates) can have a?settings(...)postfix, with which you can set the JavaBean properties of the resultingTemplateLoader. For example:<param-value>/templates?settings(attemptFileAccess=false, URLConnectionUsesCaches=false)</param-value> -
Added
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 isfalse, andtrueis only meant for development, not for production installations. The default can be overridden by setting theorg.freemarker.emulateCaseSensitiveFileSystemsystem property totrue. -
Bug fixed [424]:
WebappTemplateLoaderdidn't find templates that are stored inWEB-INF/lib/*.jar/META-INF/resources. Files under that directory are visible asServletContextresources since Servlet 3.0, yetWebappTemplateLoaderhas 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 theTemplateconstructor, and so now an exception will be thrown as expected. -
Bug fixed:
InvalidReferenceException.FAST_INSTANCEcould accidentally store reference to anEnvironmentinstance, which hence was never garbage collected. -
Bug fixed [426]: 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. Settingincompatible_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.current_template_nameor.main_template_nameinstead.) -
Bug fixed [53]: 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 theConfigurable.setSetting(String, String)API. -
Bug fixed:
StringUtil.FTLStringLiteralEnchas escaped$(hence generating an illegal escape) and haven't escaped{after$and#. 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).
Other changes
-
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.
Notes
Changes compared to 2.3.23 RC1:
-
.current_name_nameand.main_template_nameis now missing (null) instead of""if the template has no name -
Some minor error message improvements
-
Documentation refinements
