2.3.32 - 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.32

Release date: 2023-01-12

## Changes on the FTL side

- Improved outputting values for computer/parser consumption (such as for generating JSON, JavaScript values, values encoded into URL-s):

  - Added new configuration setting, `c_format` (also settable via the `setting` directive). This specifies what syntax to use when formatting values for computer consumption/parser, like `"JSON"`. Most prominently, this affects the `c` built-in, hence the name. See valid setting values, and their meaning here: Template Author's Guide/Miscellaneous/Formatting for humans, or for computers.

    If you set the `incompatible_improvements` setting to 2.3.32, the default of `c_format` changes from `"legacy"` to `"JavaScript or JSON"`, which is a format that most targets can parse (because we just format simple values, not lists and maps). With lower `incompatible_improvements`, the default value is `"legacy"` that emulates the old behavior of `?c` (where you can lose numerical precision, etc.), so it's recommended to set it to something else.

  - `?c` now formats string values to string literals (with quotation marks and escaping), according the language specified in the `c_format` setting, such as `JSON`, `Java`, etc. Earlier, `?c` only allowed numbers, and booleans.

    To generate JSON, you can now write a piece of template like this:

    Template

        "fullName": ${user.fullName?c},

    Then the output will be like:

    Output

        "fullName": "John Doe",

    Note that the quotation marks were added by `?c`, and weren't typed into the template.

  - Added ?cn, which is like `?c`, except if the value is `null`/missing, it will output a `null` literal, according the language specified in the new `c_format` setting.

    Let's say, in the previous example `user.fullName` is expected to be `null` sometimes. Then you can just use `?cn` instead if `?c`:

    Template

        "fullName": ${user.fullName?cn},

    If said variable is `null`, the output will be like this (otherwise it will be a quoted string like earlier):

    Output

        "fullName": null,

    Note that with this approach you don't complicate the template anymore to avoid printing quotation marks. Of course, `?cn` works on numerical and boolean values as well (and of course those won't be quoted, only strings).

  - `c_format`-s other than `"legacy"` use slightly different number formatting than `?c` did in earlier versions. The change affects some non-whole numbers, and whole numbers with over 100 digits. The goal of this change is to make the formatting lossless, and also to avoiding huge output with exponents of high magnitude. See details at the documentation of the `c` built-in.

    Setting the `incompatible_improvements` setting to 2.3.32 will change the default of `c_format` for `"legacy"` to `"JavaScript or JSON"`, and therefore changes number formatting too.

    Of course, all this only affects number formatting done with `?c`, `?cn`, and with `"c"` (or `"computer"`) `number_format`, and not number formatting in general.

  - For consistency, when setting the `number_format` setting (also when formatting with `?string(format)`), now `"c"` can be used instead of "computer". Both has the same effect on formatting, but `"c"` is preferred from now on.

- FREEMARKER-208: Added `?c_lower_case`, and `?c_upper_case`, which are the non-localized (computer language) variants of `?lower_case`, and `?upper_case`. The primary problem people run into with the localized versions is that with Turkish locale the letter `i`, and `I` has different conversions than in most languages, which causes problem if the conversion was for computer consumption (for technical purposes), and not for humans.

- In `freemarker.ext.xml`, which is the old, long deprecated XML wrapper, that almost nobody uses anymore (the commonly used one is `freemarker.ext.dom`), the `_registerNamespace` key now works, doing what the documentation always stated. Before this fix it just behaved as if it was the name of an element you are looking for.

## Changes on the Java side

- Added `Configurable.setCFormat(CFormat)`, with the usual accompanying setting API methods/constants. See the `c_format`-, and the `?c`-related changes earlier in the FTL section.

- Added `Environment.getCTemplateNumberFormat()` that returns a `freemarker.core.TemplateNumberFormat`, and deprecated `getCNumberFormat()` that returns a `java.text.NumberFormat`. The behavior defined in the `CFormat` (see earlier) is only reflected exactly by the return value of the new method. The deprecated method returns a format that's a best effort approximation.

- Added `freemarker.core.MarkupOutputFormat.outputForeign(MO2 mo, Writer out)` method, which for a `MarkupOutputFormat` where `isOutputFormatMixingAllowed()` returns `true`, allows full control over how to print a different markup into it. This can check what other markup is allowed, and do conversion if necessary. (GitHub PR 83)

- Fixed performance bug with XML processing (`freemarker.ext.dom`) when converting an XML element that contains lots of text nodes (instead of a single big text node) to a string. (GitHub PR 82)

- Improved `StringUtil.jsStringEnc` and `javaSctringEnc` to support quoting. Also `jsStringEnc` now have a mode that targets both JavaScript and JSON, and doesn't give up apostrophe escaping.

- FREEMARKER-198: Fixed possible deadlock when the `Configuration`, and `DefaultObjectWrapper` class static initialization is triggered in different threads around the same time. (In the very unlikely case your application can run into this, this will hang the code that initializes FreeMarker before it has processed any templates, and it can't happen anymore if any template processing managed to start.)

- FREEMARKER-190: Updated dom4j version used during FreeMarker project compilation from 1.3 to 2.1.3. Users can still use FreeMarker with dom4j 1.3 (mostly just luck, but it works). FreeMarker's dom4j support is long deprecated anyway, and almost nobody uses it anyway. We were forced to do this change because old dom4j versions have security vulnerabilities, and although FreeMarker is not affected by them (like we do not pull in dom4j as dependency into the projects of our users), we were flagged as vulnerable at certain places for merely supporting 1.3.

- Slightly improved `DefaultMemberAccessPolicy-rules` (used by default), and `unsafeMethods.properties` (long deprecated, not used by default). Note that no matter how much we tweak these, they will never provide proper security if you have untrusted templates! See this in the FAQ!

Previous Next