Quarkus Freemarker
Freemarker is a very popular and mature templating engine. Its integration as a Quarkus extension provides developers ease of configuration, and offers support for native images. In this guide, you will learn how to easily render Freemarker templates in your application.
Hello World
If you want to use Freemarker you need to add the quarkiverse-freemarker
extension first.
In your pom.xml
file, add:
<dependency>
<groupId>io.quarkiverse</groupId>
<artifactId>quarkiverse-freemarker</artifactId>
<version>{project-version}</version>
</dependency>
We’ll start with a very simple template:
Hello ${name}! (1)
1 | ${name} is a value expression that is evaluated when the template is rendered. |
Now let’s inject the template in the resource class.
package org.acme.quarkus.sample;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import freemarker.template.Template;
import io.quarkiverse.freemarker.runtime.TemplatePath;
@Path("hello")
public class HelloResource {
@Inject
@TemplatePath("hello.ftl") (1)
Template hello;
@GET
@Produces(TEXT_PLAIN)
public String hello(@QueryParam("name") String name) throws IOException, TemplateException {
StringWriter stringWriter = new StringWriter();
hello.process(Map.of("name", name), stringWriter); (2)
return stringWriter.toString();
}
}
1 | The @TemplatePath qualifier specifies the template name, found in either jar resource paths or external file paths. |
2 | Map.of("name", name) provides the model. |
If your application is running, you can request the endpoint:
$ curl -w "\n" http://localhost:8080/hello?name=bob
Hello bob!
Usage
The application code can either directly inject a Freemarker Template
bean as we saw above.
In that case it must provide a TemplatePath
qualifier annotation with the name
of the template to select.
Or it can inject a Freemarker Configuration
bean, from which templates
can be obtained programmatically. The Configuration
is a Singleton
DefaultBean
that can be replaced by an application provided implementation.
The default Configuration
bean is configured from quarkus exposed
properties. Among those, 2 are build time:
-
resource-paths
is a list of resource paths contained in the classpath (e.g. typically in jars of the application). Each path is traversed recursively, and all files get added as native resources when building a native image. -
directives
is a map of directive alias to directive class name. Each directive class is added as a shared variable in theConfiguration
bean.
Here is an example of using a Configuration
bean instead of a Template
bean:
@Inject
Configuration configuration;
@GET
@Produces(TEXT_PLAIN)
public String hello(@QueryParam("name") String name, @QueryParam("ftl") String ftl) throws IOException, TemplateException {
StringWriter stringWriter = new StringWriter();
configuration.getTemplate(ftl).process(model, stringWriter);
return stringWriter.toString();
}
The rest of the configuration properties can be provided at runtime, such as
a list of external filesystem paths where to find additional templates,
and optional properties that can be configured on the Freemarker Configuration
class.
Directives
Freemarker can be extended using custom directives. For instance if we wanted
to transform some text in base64
, we could write:
package org.acme.quarkus.sample;
public class Base64Directive implements TemplateDirectiveModel {
@Override
public void execute(Environment environment, Map map, TemplateModel[] templateModels, TemplateDirectiveBody body)
throws TemplateException, IOException {
StringWriter sw = new StringWriter();
body.render(sw);
byte[] bytes = Base64.getEncoder().encode(sw.toString().getBytes(UTF_8));
environment.getOut().write(new String(bytes, UTF_8));
}
}
Then we would have to configure the application with:
quarkus.freemarker.directives.base64=org.acme.quarkus.sample.Base64Directive
And finally, we would use it in templates such as:
Hello <@base64>$\{name}</@base64>!
This would be rendered as:
Hello Ym9i!
Data model
Freemarker supports Map
or Object
based data models.
When using objects, it is important to configure
quarkus.freemarker.object-wrapper-expose-fields=true
if model classes
do not have getters.
Additionnaly, they should be annotated with
@RegisterForReflection
to support native images.
Extension Configuration Reference
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Type |
Default |
|
---|---|---|
Comma-separated list of absolute resource paths to scan recursively for templates. All tree folder from 'resource-paths' will be added as a resource. Unprefixed locations or locations starting with classpath will be processed in the same way.
Defaults relevant for this option are documented on Environment variable: |
list of string |
|
The base path of this template set. Template set is a triple of Environment variable: |
string |
|
A comma separated list of globs to select FreeMarker templates for inclusion in the native image.
Environment variable: |
list of string |
|
A comma separated list of globs not to include in the native image.
Environment variable: |
list of string |
|
Comma-separated of file system paths where freemarker templates are located Environment variable: |
list of string |
|
Set the preferred charset template files are stored in. Environment variable: |
string |
|
Sets how errors will appear. rethrow, debug, html-debug, ignore. Environment variable: |
string |
|
If false, don’t log exceptions inside FreeMarker that it will be thrown at you anyway. Environment variable: |
boolean |
|
Wrap unchecked exceptions thrown during template processing into TemplateException-s. Environment variable: |
boolean |
|
If false, do not fall back to higher scopes when reading a null loop variable. Environment variable: |
boolean |
|
The string value for the boolean Environment variable: |
string |
|
Sets the default number format used to convert numbers to strings. Environment variable: |
string |
|
If true, the object wrapper will be configured to expose fields. Environment variable: |
boolean |
|
List of directives to register with format name=classname Environment variable: |
|
|
Type |
Default |
|
The base path of this template set. Template set is a triple of Environment variable: |
string |
|
A comma separated list of globs to select FreeMarker templates for inclusion in the native image.
Environment variable: |
list of string |
|
A comma separated list of globs not to include in the native image.
Environment variable: |
list of string |