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 thesettingdirective). This specifies what syntax to use when formatting values for computer consumption/parser, like"JSON". Most prominently, this affects thecbuilt-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_improvementssetting to 2.3.32, the default ofc_formatchanges 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 lowerincompatible_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. -
?cnow formats string values to string literals (with quotation marks and escaping), according the language specified in thec_formatsetting, such asJSON,Java, etc. Earlier,?conly 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 isnull/missing, it will output anullliteral, according the language specified in the newc_formatsetting.Let's say, in the previous example
user.fullNameis expected to benullsometimes. Then you can just use?cninstead 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,
?cnworks 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?cdid 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 thecbuilt-in.Setting the
incompatible_improvementssetting to 2.3.32 will change the default ofc_formatfor"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_formatsetting (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 letteri, andIhas 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 isfreemarker.ext.dom), the_registerNamespacekey 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 thec_format-, and the?c-related changes earlier in the FTL section. -
Added
Environment.getCTemplateNumberFormat()that returns afreemarker.core.TemplateNumberFormat, and deprecatedgetCNumberFormat()that returns ajava.text.NumberFormat. The behavior defined in theCFormat(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 aMarkupOutputFormatwhereisOutputFormatMixingAllowed()returnstrue, 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.jsStringEncandjavaSctringEncto support quoting. AlsojsStringEncnow have a mode that targets both JavaScript and JSON, and doesn't give up apostrophe escaping. -
FREEMARKER-198: Fixed possible deadlock when the
Configuration, andDefaultObjectWrapperclass 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), andunsafeMethods.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!
