Associating output formats with templates

The output format associated to a template decides if and what kind of auto-escaping is used in that template (unless the template overrides that with directives). By default, templates have "undefined" output format associated, which does no escaping, and in general gives the behavior that you would expect from a template engine that doesn't care about output formats and escaping. However, if the recognize_standard_file_extensions setting is true (which is the default with the incompatible_improvements setting set to 2.3.24 or higher), templates whose source name ends with ".ftlh" gets "HTML" output format, and those with ".ftlx" get "XML" output format. Using the ftlh and ftlx file extensions is the recommended way of activating HTML and XML auto-escaping. You can also associate output formats to templates based on arbitrary name patterns with the template_configurations setting; see some examples of that below.

There's another a related setting, called auto_escaping_policy, which can be used to disable auto-escaping even if the current output format supports it, or enable auto-escaping even if the format by default doesn't escape (but it supports it). Using this setting rarely advisable, as it's potentially confusing for the template authors. (Instead, escaping can be turned on/off explicitly inside the templates with the auto_esc parameter of the ftl directive, or with the noautoesc and autoesc directives.)

To check if you have configured FreeMarker properly, you can use this template:

Template
<p>Output format: ${.output_format}
<p>Auto-escaping: ${.auto_esc?c}

See the table of predefined output formats here...

Configuration examples:

  • To enable automatic output format associations to *.ftlh and *.ftlx, either:

    • Use incompatible_improvements 2.3.24 or higher; see how to set incompatible_improvements

    • Or, enable standard file extension recognizing explicitly:

      // Where you initalize the Configuration singletion, add:
      cfg.setRecognizeStandardFileExtensions(true);

      or if you configure FreeMarker with Java *.properties file:

      recognizeStandardFileExtensions = true
  • Let's say that you want to associate all templates in the mail directory to the HTML output format. You could achieve that like this (assuming that you are getting the templates with cfg.getTemplate(...), and not instantiating them yourself):

    // Where you initalize the Configuration singletion, add:
    
    TemplateConfiguration tcHTML = new TemplateConfiguration();
    tcHTML.setOutputFormat(HTMLOutputFormat.INSTANCE);
    
    cfg.setTemplateConfigurations(
            new ConditionalTemplateConfigurationFactory(
                    new PathGlobMatcher("mail/**"),
                    tcHTML));

    or if you are configuring FreeMarker from Java *.properties file (the \-s are required for the Java Properties file format only):

    templateConfigurations = \
        ConditionalTemplateConfigurationFactory( \
            PathGlobMatcher("mail/**"), \
            TemplateConfiguration(outputFormat = HTMLOutputFormat()))
  • Let's say you want to associate templates with xml file extension to the XML output format, templates with html and htm extension to the HTML output format, and templates with rtf extension to the RTF output format. You could achieve that like this (assuming that you are getting the templates with cfg.getTemplate(...), and not instantiating them yourself):

    TemplateConfiguration tcHTML = new TemplateConfiguration();
    tcHTML.setOutputFormat(HTMLOutputFormat.INSTANCE);
    
    TemplateConfiguration tcXML = new TemplateConfiguration();
    tcXML.setOutputFormat(XMLOutputFormat.INSTANCE);
    
    TemplateConfiguration tcRTF = new TemplateConfiguration();
    tcRTF.setOutputFormat(RTFOutputFormat.INSTANCE);
    
    cfg.setTemplateConfigurations(
            new FirstMatchTemplateConfigurationFactory(
                    new ConditionalTemplateConfigurationFactory(
                            new FileExtensionMatcher("xml"),
                            tcXML),
                    new ConditionalTemplateConfigurationFactory(
                            new OrMatcher(
                                    new FileExtensionMatcher("html"),
                                    new FileExtensionMatcher("htm")),
                            tcHTML),
                    new ConditionalTemplateConfigurationFactory(
                            new FileExtensionMatcher("rtf"),
                            tcRTF)
            ).allowNoMatch(true)
    );

    or if you are configuring FreeMarker from Java *.properties file (the \-s are required for the Java Properties file format only):

    templateConfigurations = \
        FirstMatchTemplateConfigurationFactory( \
            ConditionalTemplateConfigurationFactory( \
                FileExtensionMatcher("xml"), \
                TemplateConfiguration(outputFormat = XMLOutputFormat())), \
            ConditionalTemplateConfigurationFactory( \
                OrMatcher( \
                    FileExtensionMatcher("html"), \
                    FileExtensionMatcher("htm")), \
                TemplateConfiguration(outputFormat = HTMLOutputFormat())), \
            ConditionalTemplateConfigurationFactory( \
                FileExtensionMatcher("rtf"), \
                TemplateConfiguration(outputFormat = RTFOutputFormat())), \
            allowNoMatch = true)

(You can find some more complex template_configurations setups here...)