“Have patience. All things are difficult before they become easy.“
Saadi
Some additions to a framework are so trivial that they don’t really deserve their own article. On the other hand, as a developer, you may ask yourself why this addition has taken so long.
FreshMarker is a lightweight template engine that is based on the syntax of FreeMarker. In contrast to FreeMarker, however, a whole range of features such as include, import, namespaces and XML processing are not implemented. Instead, FreshMarker shines with a plug-in system that allows support for temporal data types, paths, files, international phonenumbers and public holidays.
For unknown data types, FreshMarker uses the interpretation of the class as a Java Bean by default. This is a good solution for many POJO, DTO and Entity classes, but in some cases the class should be used as a primitive FreshMarker type.
In the following example, the Leitweg-ID from the article Leitweg ID – Ihre Nummer für die Behörde is to be output. As the Leitweg-ID is not supported by FreshMarker by default, we receive an error message. For FreshMarker, it looks as if a bean was addressed for output in the template and not a primitive type.
Configuration configuration = new Configuration(); Template template = configuration.getTemplate("id", "Leitweg-ID: ${id}!"); LeitwegId leitwegId = LeitwegId.parse("04011000-1234512345-06"); assertEquals("Leitweg-ID: 04011000-1234512345-06!", template.process(Map.of("id", leitwegId)));
In order for the Leitweg-ID to be output, either one of its attributes had to be specified or a separate plug-in had to be written. As there is no corresponding attribute for output in the Leitweg-ID, another solution must be found. The Leitweg-ID has a toString
method to generate the desired display. The only thing missing is a simple way to create a TemplateString
object from the Leitweg-ID.
Fortunately, FreshMarker has an internal map in which all supported types have a mapping to a FreshMarker model class. The only thing missing is a method for entering your own mapping there.
In the following example, the newly added Configuration#registerSimpleMapping
method is used to create a mapping to TemplateString
for the LeitwegId
class.
Configuration configuration = new Configuration(); configuration.registerSimpleMapping(LeitwegId.class); Template template = configuration.getTemplate("id", "Leitweg-ID: ${id}!"); LeitwegId leitwegId = LeitwegId.parse("04011000-1234512345-06"); assertEquals("Leitweg-ID: 04011000-1234512345-06!", template.process(Map.of("id", leitwegId)));
Another method is available for more complex mapping.
Configuration configuration = new Configuration(); configuration.registerSimpleMapping(LeitwegId.class, x -> "<<" + x + ">>"); Template template = configuration.getTemplate("id", "Leitweg-ID: ${id}!"); LeitwegId leitwegId = LeitwegId.parse("04011000-1234512345-06"); assertEquals("Leitweg-ID: <<04011000-1234512345-06>>!", template.process(Map.of("id", leitwegId)));
This feature is available in the latest version of FreshMarker on Maven Central.
<dependency> <groupId>de.schegge</groupId> <artifactId>freshmarker</artifactId> <version>0.5.5</version> </dependency>