2.3.23 - Apache FreeMarker Manual

Unsupported web browser - Use a modern browser to view this website!

- Home
- Manual
- Java API

- Contribute
- Report a Bug
- Download

Manual
Previous Next

# 2.3.23

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 `list` directive child directives. There are `else` and `items` to deal with special cases with 0-length lists, and `sep` for inserting separators between items. For more details, see the `list` directive in the Reference.

  - New built-ins that act on loop variables: `var?index` (deprecates `var_index`), `var?counter` (1-based index), `var?has_next` (deprecates `var_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`, `#global` and `#local` currently) 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 `then` built-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 `switch` built-in, which can be used like an in-line (expression) switch-case-default statement: `someValue?switch(case1, result1, case2, result2, ... caseN, resultN, defaultResult)`, where `defaultResult` can 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 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, `.current_template_name` and `.main_template_name`. These deprecate `.template_name`, which was always broken when it comes to macro calls. The new `.current_template_name` always returns the name of the template that contains the reference to the special variable, and `.main_template_name` always 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 that `someMap` is not a sequence nor is coercible to string.

- Bug fixed, activated with setting `incompatible_improvements` to 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 `#list` or `#switch`. This check could be circumvented with `#macro` or `#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 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 `defaultEncoding=utf-8` instead of `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.

- Added `Configuration.setTemplateUpdateDelayMilliseconds(long)` and `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.)

- The `template_update_delay` setting, when specified as a string (as inside `java.util.Properties`), supports time units, like in `template_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 since `incompatible_improvements` 2.3.21) probably solves that on modern Servlet containers.

- In the `FreemarkerServlet` `TemplatePath` init-param, paths (like `/templates`) can have a `?settings(...)` postfix, with which you can set the JavaBean properties of the resulting `TemplateLoader`. 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 is `false`, and `true` is only meant for development, not for production installations. The default can be overridden by setting the `org.freemarker.emulateCaseSensitiveFileSystem` system property to `true`.

- Bug fixed [424]: `WebappTemplateLoader` didn't find templates that are stored in `WEB-INF/lib/*.jar/META-INF/resources`. Files under that directory are visible as `ServletContext` resources since Servlet 3.0, yet `WebappTemplateLoader` has 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 `IOException` during 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 `Template` constructor, and so now an exception will be thrown as expected.

- Bug fixed: `InvalidReferenceException.FAST_INSTANCE` could accidentally store reference to an `Environment` instance, which hence was never garbage collected.

- Bug fixed [426]: When setting `incompatible_improvements` to 2.3.22, the special variable reference `.template_name` in templates always returns the name of the main (topmost) template, due to an oversight in 2.3.22. Setting `incompatible_improvements` to 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_name` or `.main_template_name` instead.)

- 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_exceptions` setting (added in 2.3.22) couldn't be set through the `Configurable.setSetting(String, String)` API.

- Bug fixed: `StringUtil.FTLStringLiteralEnc` has 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_name` and `.main_template_name` is now missing (`null`) instead of `""` if the template has no name

- Some minor error message improvements

- Documentation refinements

Previous Next