Template configurations - Apache FreeMarker Manual

Unsupported web browser - Use a modern browser to view this website!

- Home
- Manual
- Java API

- Contribute
- Report a Bug
- Download

Manual
Previous Next

# Template configurations

"Template configurations" refers to the `template_configurations` setting of `Configuration` (`Configuration.setTemplateConfigurations(...)`). This setting lets you override individual settings coming from the common `Configuration` object, depending on the name (path) of the template.

It's important to understand, however, that this setting only has effect if you get templates with `Configuration.getTemplate(...)`, not when you create templates directly with the `Template` constructors. In that case it's up to you to invoke this mechanism (see `TemplateCache` source code as an example).

You will use these kind of objects to declare your template configuration rules:

- `TemplateConfiguration`-s: These store the actual setting assignments that you want to apply. For example, this `TemplateConfiguration` will set the encoding and the output format of the matched template (and leave all other settings of it alone):

      TemplateConfiguration tcUTF8XML = new TemplateConfiguration();
      tc.setEncoding("utf-8");
      tc.setOutputFormat(XMLOutputFormat.INSTANCE);

- `TemplateSourceMatcher` (abstract) subclasses: These define a rule that matches templates based on their source name (their source path; as in `Template.getSourceName()`), and possibly on other `TemplateLoader`-dependent properties. For example, `new FileExtensionMatcher("xml")` matches templates that has `xml` file extension. See all the subclasses in the Java API documentation.

- `TemplateConfigurationFactory`-es: This is what connects `TemplateConfiguration`-s and `TemplateSourceMatcher`-s together. This is the Java type of the `template_configurations` setting. See the examples below for more.

## Example 1

This setup combines our earlier two example objects with a `ConditionalTemplateConfigurationFactory`, causing all templates with `xml` extension to get UTF-8 encoding and XML output format:

    cfg.setTemplateConfigurations(
            new ConditionalTemplateConfigurationFactory(
                    new FileExtensionMatcher("xml"),
                    tcUTF8XML));

The same configuring is also doable if you don't have access to the configuring Java code, but only to a Java `*.properties` file, or other kind of string-string key value pairs (the `\`-s are prescribed by the Java Properties file format for multi-line values, so omit them elsewhere):

    templateConfigurations = \
        ConditionalTemplateConfigurationFactory( \
            FileExtensionMatcher("xml"), \
            TemplateConfiguration( \
                encoding = "utf-8", \
                outputFormat = XMLOutputFormat() \
            ) \
        )

## Example 2

Let's say you only need to handle templates in the `mail` directory specially, other templates can use the setting coming from the shared `Configuration` singleton. The names of templates there must contain `".subject."` or `".body."`. Subject templates must get `plainText` output format, while body templates must get `HTML` output format. So we have to make a choice here, and that's when you need a `FirstMatchTemplateConfigurationFactory`.

Assuming `cfg` stores the shared `Configuration` singleton, you set this up like this:

    TemplateConfiguration tcSubject = new TemplateConfiguration();
    tcSubject.setOutputFormat(PlainTextOutputFormat.INSTANCE);

    TemplateConfiguration tcBody = new TemplateConfiguration();
    tcBody.setOutputFormat(HTMLOutputFormat.INSTANCE);

    cfg.setTemplateConfigurations(
            new ConditionalTemplateConfigurationFactory(
                    new PathGlobMatcher("mail/**"),
                    new FirstMatchTemplateConfigurationFactory(
                            new ConditionalTemplateConfigurationFactory(
                                    new FileNameGlobMatcher("*.subject.*"),
                                    tcSubject),
                            new ConditionalTemplateConfigurationFactory(
                                    new FileNameGlobMatcher("*.body.*"),
                                    tcBody)
                            )
                            .noMatchErrorDetails(
                                    "Mail template names must contain \".subject.\" or \".body.\"!")
                    ));

The equivalent configuration using a Java `*.properties` file or other kind of string-string key value pairs (the `\`-s are prescribed by the Java Properties file format only, so omit them elsewhere):

    templateConfigurations = \
        ConditionalTemplateConfigurationFactory( \
            PathGlobMatcher("mail/**"), \
            FirstMatchTemplateConfigurationFactory( \
                ConditionalTemplateConfigurationFactory( \
                    FileNameGlobMatcher("*.subject.*"), \
                    TemplateConfiguration(outputFormat = PlainTextOutputFormat()) \
                ), \
                ConditionalTemplateConfigurationFactory( \
                    FileNameGlobMatcher("*.body.*"), \
                    TemplateConfiguration(outputFormat = HTMLOutputFormat()) \
                ), \
                noMatchErrorDetails = 'Mail template names must contain ".subject." or ".body."!' \
            ) \
        )

## Example 3

Let's say you want the following deviations from the shared `Configuration` settings in your application:

- All templates whose name contains `".stats."` should use ISO date/time format and UTC time zone

- All templates inside the `mail` directory should use UTF-8 encoding

- Templates with `xml` file extension should use XML `output_format`, templates with `html` or `htm` extension should use HTML output format. For other templates, the shared `Configuration` can dictate the `output_format`.

Here we have 3 independent concerns, and possibly multiple (or none) of those apply to a template; that's when you need a `MergingTemplateConfigurationFactory`. In file extension related rule above you have mutually exclusive choices, so you need a `FirstMatchTemplateConfigurationFactory`, but this time no choice is also allowed. Here's the source code, assuming `cfg` stores the shared `Configuration` instance:

    TemplateConfiguration tcStats = new TemplateConfiguration();
    tcStats.setDateTimeFormat("iso");
    tcStats.setDateFormat("iso");
    tcStats.setTimeFormat("iso");
    tcStats.setTimeZone(DateUtil.UTC);

    TemplateConfiguration tcMail = new TemplateConfiguration();
    tcMail.setEncoding("utf-8");

    TemplateConfiguration tcHTML = new TemplateConfiguration();
    tcHTML.setOutputFormat(HTMLOutputFormat.INSTANCE);

    TemplateConfiguration tcXML = new TemplateConfiguration();
    tcXML.setOutputFormat(XMLOutputFormat.INSTANCE);

    cfg.setTemplateConfigurations(
            new MergingTemplateConfigurationFactory(
                    new ConditionalTemplateConfigurationFactory(
                            new FileNameGlobMatcher("*.stats.*"),
                            tcStats),
                    new ConditionalTemplateConfigurationFactory(
                            new PathGlobMatcher("mail/**"),
                            tcMail),
                    new FirstMatchTemplateConfigurationFactory(
                            new ConditionalTemplateConfigurationFactory(
                                    new FileExtensionMatcher("xml"),
                                    tcXML),
                            new ConditionalTemplateConfigurationFactory(
                                    new OrMatcher(
                                            new FileExtensionMatcher("html"),
                                            new FileExtensionMatcher("htm")),
                                    tcHTML)
                    ).allowNoMatch(true)
            )
    );

The equivalent configuration using a Java `*.properties` file or other kind of string-string key value pairs (the `\`-s are prescribed by the Java Properties file format only):

    templateConfigurations = \
        MergingTemplateConfigurationFactory( \
            ConditionalTemplateConfigurationFactory( \
                FileNameGlobMatcher("*.stats.*"), \
                TemplateConfiguration( \
                    dateTimeFormat = "iso", \
                    dateFormat = "iso", \
                    timeFormat = "iso", \
                    timeZone = TimeZone("UTC") \
                ) \
            ), \
            ConditionalTemplateConfigurationFactory( \
                PathGlobMatcher("mail/**"), \
                TemplateConfiguration(encoding = "utf-8") \
            ), \
            FirstMatchTemplateConfigurationFactory( \
                ConditionalTemplateConfigurationFactory( \
                    FileExtensionMatcher("xml"), \
                    TemplateConfiguration(outputFormat = XMLOutputFormat()) \
                ), \
                ConditionalTemplateConfigurationFactory( \
                    OrMatcher( \
                        FileExtensionMatcher("html"), \
                        FileExtensionMatcher("htm") \
                    ), \
                    TemplateConfiguration(outputFormat = HTMLOutputFormat()) \
                ), \
                allowNoMatch = true \
            ) \
        )

Previous Next