Release date: 2020-03-05
Please note that with this version the minimum required Java version was increased from Java 5 to Java 7.
Changes on the FTL side
-
FREEMARKER-107: Added
?with_args(dynamicArguments)
and?with_args_last(dynamicArguments)
to add parameters dynamically to directive (like macro), function and method calls. Actually, this built-in returns a directive or macro or function that has different parameter defaults. See more here... -
FREEMARKER-107: Added new special variable,
.args
. This evaluates to a hash in macros, and to a sequence in functions, which contains all the arguments. This is useful for operations that act on all the arguments uniformly, like for example to pass the arguments to?with_args(...)
. -
Macro catch-all parameters (aka. varargs parameters), when capture arguments passed by name (as opposed to by position), now keep the original order of arguments. Earlier the order wasn't predictable.
-
Bug fixed: In
<#escape placeholder as escExpression>
, theplaceholder
wasn't substituted inside lambda expressions insideescExpression
. Fortunately it's very unlikely that anyone wanted to use lambdas there (given the few built-ins that accept lambdas).
Changes on the Java side
-
The minimum required Java version was increased from Java 5 to Java 7.
-
FREEMARKER-124: Made the default filtering of class members more restrictive (when you are using
BeansWrapper
, or its subclasses likeDefaultObjectWrapper
). This is not strictly backward compatible, but unlikely to break any real-world applications; seesrc/main/resources/freemarker/ext/beans/DefaultMemberAccessPolicy-rules
to see what was changed. This change was made for security reasons, but the default behavior will never be safe enough if untrusted users will edit templates; see in the FAQ. In the unlikely case this change breaks your application, then you can still use the old behavior by setting thememberAccessPolicy
property of the object wrapper toLegacyDefaultMemberAccessPolicy.INSTANCE
. -
Added
freemarker.ext.beans.MemberAccessPolicy
interface, and thememberAccessPolicy
property toBeansWrapper
, and subclasses likeDefaultObjectWrapper
. This allows users to implement their own program logic to decide what members of classes will be exposed to the templates. See See the FreeMarker Java API documentation for more details. -
Added
freemarker.ext.beans.WhitelistMemberAccessPolicy
, which is aMemberAccessPolicy
for use cases where you want to allow editing templates to users who shouldn't have the same rights as the developers (the same rights as the Java application). Earlier, the only out of the box solution for that wasSimpleObjectWrapper
, but that's too restrictive for most applications where FreeMarker is used.WhitelistMemberAccessPolicy
works withDefaultObjectWrapper
(or any otherBeansWrapper
), allowing you to use all features of it, but it will only allow accessing members that were explicitly listed by the developers, or was annotated with@TemplateAccessible
. -
FREEMARKER-125: FreeMarker now picks up
DecimalFormatSymbols
provided by theDecimalFormatSymbolsProvider
SPI. This is useful if you need to change the decimal format symbols provided for a locale by Java. -
FREEMARKER-120:
BeansWrapper
(and it's subclasses likeDefaultObjectWrapper
) now has two protected methods that can be overridden to monitor the accessing of members:invokeMethod
andreadField
. -
Setting
incompatibleImprovements
to the instance returned byConfiguration.getVersion()
will now be logged as an error, but for backward compatibility it will still work. This applies to said setting ofConfiguration
,DefaultObjectWrapper
, andBeansWrapper
. The typical bad pattern is this:new Configuration(Configuration.getVersion())
. Doing that defeats the purpose ofincompatibleImprovements
, and makes upgrading FreeMarker a potentially breaking change. Furthermore, doing this probably won't be allowed starting from 2.4.0, and will throw exception. So if above mistake is present in your application, it should be fixed by settingincompatibleImprovements
to the highest concrete version that's known to be compatible with the application. -
Added
Environment.getDataModelOrSharedVariable(String)
. -
Bug fixed: AST traversal API now can properly traverse the inside of lambda expressions (such as the parameter list)
-
Added a new
SimpleHash
constructor, where the caller can provide theMap
instance used as the backing storage, thus allows controlling the ordering, and other technical aspects (like the initial capacity) of it.