After two months of development, I’m pleased to announce the release of FreshMarker version 2.7.0. This time, the focus was on functional hash processing, more flexible formatting, and a major step toward a more consistent template syntax. Overall, it’s a well-rounded mix of new expression capabilities and improved code quality in templates.
New Features
- Hash built-ins map and filter – Following sequences, hashes can now also be functionally transformed and filtered. This allows complex data structures to be processed elegantly in a single expression without having to iterate over temporary variables.
- Iteration over enum hashes – Enum hashes can now be used directly in list directives.
- Parameters for the Nested Directive – Macros can now pass values to the nested block when calling
<#nested/>. This opens up new possibilities for macros. - Extended Partial Expression Reduction – The previously experimental reduction of expressions has been extended to more directives. Additionally, list directives with ranges are now expanded during partial reduction, resulting in more efficient preprocessed templates.
- withBooleanFormat, withNumberFormat, withCollator – three new builder methods allow for fine-grained control of formatting directly during template creation. withCollator also enables localized string comparisons.
- boolean_format and number_format in the setting directive – Formatting can now also be customized within a template using
<#setting>without having to define it in the Java code..
Deprecation
The loose-end syntax for set, assign, var, setting, import, include, return, and nested is now deprecated. Previously, for example, you could write <#nested> instead of <#nested/>—this will be removed in a future version. During the transition period, SystemFeature.LOOSE_END_TAG is enabled so that existing templates continue to work and can be migrated gradually.
Bugfix
End-tag names in user directives are now checked correctly—a different name now results in an error instead of being silently accepted. Here, too, the old syntax can be retained for a transitional period using SystemFeature.STRICT_USER_TAG.