Class Configuration

  • All Implemented Interfaces:
    ParserConfiguration, java.lang.Cloneable

    public class Configuration
    extends Configurable
    implements java.lang.Cloneable, ParserConfiguration
    The main entry point into the FreeMarker API; encapsulates the configuration settings of FreeMarker, also serves as a central template-loading and caching service.

    This class is meant to be used in a singleton pattern. That is, you create an instance of this at the beginning of the application life-cycle, set its configuration settings there (either with the setter methods like setTemplateLoader(TemplateLoader) or by loading a .properties file), and then use that single instance everywhere in your application. Frequently re-creating Configuration is a typical and grave mistake from performance standpoint, as the Configuration holds the template cache, and often also the class introspection cache, which then will be lost. (Note that, naturally, having multiple long-lived instances, like one per component that internally uses FreeMarker is fine.)

    The basic usage pattern is like:

      // Where the application is initialized; in general you do this ONLY ONCE in the application life-cycle!
      Configuration cfg = new Configuration(VERSION_X_Y_Z));
      // Where VERSION_X_Y_Z enables the not-100%-backward-compatible fixes introduced in
      // FreeMarker version X.Y.Z  and earlier (see Configuration(Version)).
      cfg.setSomeSetting(...);
      cfg.setOtherSetting(...);
      ...
      
      // Later, whenever the application needs a template (so you may do this a lot, and from multiple threads):
      Template myTemplate = cfg.getTemplate("myTemplate.ftlh");
      myTemplate.process(dataModel, out);

    A couple of settings that you should not leave on its default value are:

    A Configuration object is thread-safe only after you have stopped modifying the configuration settings, and you have safely published it (see JSR 133 and related literature) to other threads. Generally, you set everything directly after you have instantiated the Configuration object, then you don't change the settings anymore, so then it's safe to make it accessible (again, via a "safe publication" technique) from multiple threads. The methods that aren't for modifying settings, like getTemplate(String), are thread-safe.

    • Field Detail

      • DEFAULT_ENCODING_KEY_SNAKE_CASE

        public static final java.lang.String DEFAULT_ENCODING_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • DEFAULT_ENCODING_KEY_CAMEL_CASE

        public static final java.lang.String DEFAULT_ENCODING_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • DEFAULT_ENCODING_KEY

        public static final java.lang.String DEFAULT_ENCODING_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • LOCALIZED_LOOKUP_KEY_SNAKE_CASE

        public static final java.lang.String LOCALIZED_LOOKUP_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • LOCALIZED_LOOKUP_KEY_CAMEL_CASE

        public static final java.lang.String LOCALIZED_LOOKUP_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • LOCALIZED_LOOKUP_KEY

        public static final java.lang.String LOCALIZED_LOOKUP_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • STRICT_SYNTAX_KEY_SNAKE_CASE

        public static final java.lang.String STRICT_SYNTAX_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • STRICT_SYNTAX_KEY_CAMEL_CASE

        public static final java.lang.String STRICT_SYNTAX_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • STRICT_SYNTAX_KEY

        public static final java.lang.String STRICT_SYNTAX_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • WHITESPACE_STRIPPING_KEY_SNAKE_CASE

        public static final java.lang.String WHITESPACE_STRIPPING_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • WHITESPACE_STRIPPING_KEY_CAMEL_CASE

        public static final java.lang.String WHITESPACE_STRIPPING_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • WHITESPACE_STRIPPING_KEY

        public static final java.lang.String WHITESPACE_STRIPPING_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • OUTPUT_FORMAT_KEY_SNAKE_CASE

        public static final java.lang.String OUTPUT_FORMAT_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.24
        See Also:
        Constant Field Values
      • OUTPUT_FORMAT_KEY_CAMEL_CASE

        public static final java.lang.String OUTPUT_FORMAT_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.24
        See Also:
        Constant Field Values
      • OUTPUT_FORMAT_KEY

        public static final java.lang.String OUTPUT_FORMAT_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_SNAKE_CASE

        public static final java.lang.String RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.24
        See Also:
        Constant Field Values
      • RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_CAMEL_CASE

        public static final java.lang.String RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.24
        See Also:
        Constant Field Values
      • RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY

        public static final java.lang.String RECOGNIZE_STANDARD_FILE_EXTENSIONS_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_SNAKE_CASE

        public static final java.lang.String REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.24
        See Also:
        Constant Field Values
      • REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_CAMEL_CASE

        public static final java.lang.String REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.24
        See Also:
        Constant Field Values
      • REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY

        public static final java.lang.String REGISTERED_CUSTOM_OUTPUT_FORMATS_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • AUTO_ESCAPING_POLICY_KEY_SNAKE_CASE

        public static final java.lang.String AUTO_ESCAPING_POLICY_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.24
        See Also:
        Constant Field Values
      • AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE

        public static final java.lang.String AUTO_ESCAPING_POLICY_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.24
        See Also:
        Constant Field Values
      • AUTO_ESCAPING_POLICY_KEY

        public static final java.lang.String AUTO_ESCAPING_POLICY_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • CACHE_STORAGE_KEY_SNAKE_CASE

        public static final java.lang.String CACHE_STORAGE_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • CACHE_STORAGE_KEY_CAMEL_CASE

        public static final java.lang.String CACHE_STORAGE_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • CACHE_STORAGE_KEY

        public static final java.lang.String CACHE_STORAGE_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • TEMPLATE_UPDATE_DELAY_KEY_SNAKE_CASE

        public static final java.lang.String TEMPLATE_UPDATE_DELAY_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • TEMPLATE_UPDATE_DELAY_KEY_CAMEL_CASE

        public static final java.lang.String TEMPLATE_UPDATE_DELAY_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • TEMPLATE_UPDATE_DELAY_KEY

        public static final java.lang.String TEMPLATE_UPDATE_DELAY_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • AUTO_INCLUDE_KEY_SNAKE_CASE

        public static final java.lang.String AUTO_INCLUDE_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • AUTO_INCLUDE_KEY_CAMEL_CASE

        public static final java.lang.String AUTO_INCLUDE_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • AUTO_INCLUDE_KEY

        public static final java.lang.String AUTO_INCLUDE_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • TAG_SYNTAX_KEY_SNAKE_CASE

        public static final java.lang.String TAG_SYNTAX_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • TAG_SYNTAX_KEY_CAMEL_CASE

        public static final java.lang.String TAG_SYNTAX_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • TAG_SYNTAX_KEY

        public static final java.lang.String TAG_SYNTAX_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • INTERPOLATION_SYNTAX_KEY_SNAKE_CASE

        public static final java.lang.String INTERPOLATION_SYNTAX_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.28
        See Also:
        Constant Field Values
      • INTERPOLATION_SYNTAX_KEY_CAMEL_CASE

        public static final java.lang.String INTERPOLATION_SYNTAX_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.28
        See Also:
        Constant Field Values
      • INTERPOLATION_SYNTAX_KEY

        public static final java.lang.String INTERPOLATION_SYNTAX_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • NAMING_CONVENTION_KEY_SNAKE_CASE

        public static final java.lang.String NAMING_CONVENTION_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • NAMING_CONVENTION_KEY_CAMEL_CASE

        public static final java.lang.String NAMING_CONVENTION_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • NAMING_CONVENTION_KEY

        public static final java.lang.String NAMING_CONVENTION_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • TAB_SIZE_KEY_SNAKE_CASE

        public static final java.lang.String TAB_SIZE_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.25
        See Also:
        Constant Field Values
      • TAB_SIZE_KEY_CAMEL_CASE

        public static final java.lang.String TAB_SIZE_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.25
        See Also:
        Constant Field Values
      • TAB_SIZE_KEY

        public static final java.lang.String TAB_SIZE_KEY
        Alias to the ..._SNAKE_CASE variation. @since 2.3.25
        See Also:
        Constant Field Values
      • TEMPLATE_LOADER_KEY_SNAKE_CASE

        public static final java.lang.String TEMPLATE_LOADER_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • TEMPLATE_LOADER_KEY_CAMEL_CASE

        public static final java.lang.String TEMPLATE_LOADER_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • TEMPLATE_LOADER_KEY

        public static final java.lang.String TEMPLATE_LOADER_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • TEMPLATE_LOOKUP_STRATEGY_KEY_SNAKE_CASE

        public static final java.lang.String TEMPLATE_LOOKUP_STRATEGY_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • TEMPLATE_LOOKUP_STRATEGY_KEY_CAMEL_CASE

        public static final java.lang.String TEMPLATE_LOOKUP_STRATEGY_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • TEMPLATE_LOOKUP_STRATEGY_KEY

        public static final java.lang.String TEMPLATE_LOOKUP_STRATEGY_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • TEMPLATE_NAME_FORMAT_KEY_SNAKE_CASE

        public static final java.lang.String TEMPLATE_NAME_FORMAT_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • TEMPLATE_NAME_FORMAT_KEY_CAMEL_CASE

        public static final java.lang.String TEMPLATE_NAME_FORMAT_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • TEMPLATE_NAME_FORMAT_KEY

        public static final java.lang.String TEMPLATE_NAME_FORMAT_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • TEMPLATE_CONFIGURATIONS_KEY_SNAKE_CASE

        public static final java.lang.String TEMPLATE_CONFIGURATIONS_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.24
        See Also:
        Constant Field Values
      • TEMPLATE_CONFIGURATIONS_KEY_CAMEL_CASE

        public static final java.lang.String TEMPLATE_CONFIGURATIONS_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.24
        See Also:
        Constant Field Values
      • TEMPLATE_CONFIGURATIONS_KEY

        public static final java.lang.String TEMPLATE_CONFIGURATIONS_KEY
        Alias to the ..._SNAKE_CASE variation. @since 2.3.24
        See Also:
        Constant Field Values
      • INCOMPATIBLE_IMPROVEMENTS_KEY_SNAKE_CASE

        public static final java.lang.String INCOMPATIBLE_IMPROVEMENTS_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • INCOMPATIBLE_IMPROVEMENTS_KEY_CAMEL_CASE

        public static final java.lang.String INCOMPATIBLE_IMPROVEMENTS_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.23
        See Also:
        Constant Field Values
      • INCOMPATIBLE_IMPROVEMENTS_KEY

        public static final java.lang.String INCOMPATIBLE_IMPROVEMENTS_KEY
        Alias to the ..._SNAKE_CASE variation due to backward compatibility constraints.
        See Also:
        Constant Field Values
      • FALLBACK_ON_NULL_LOOP_VARIABLE_KEY_SNAKE_CASE

        public static final java.lang.String FALLBACK_ON_NULL_LOOP_VARIABLE_KEY_SNAKE_CASE
        Legacy, snake case (like_this) variation of the setting name. @since 2.3.29
        See Also:
        Constant Field Values
      • FALLBACK_ON_NULL_LOOP_VARIABLE_KEY_CAMEL_CASE

        public static final java.lang.String FALLBACK_ON_NULL_LOOP_VARIABLE_KEY_CAMEL_CASE
        Modern, camel case (likeThis) variation of the setting name. @since 2.3.29
        See Also:
        Constant Field Values
      • FALLBACK_ON_NULL_LOOP_VARIABLE_KEY

        public static final java.lang.String FALLBACK_ON_NULL_LOOP_VARIABLE_KEY
        Alias to the ..._SNAKE_CASE variation. @since 2.3.25
        See Also:
        Constant Field Values
      • ANGLE_BRACKET_TAG_SYNTAX

        public static final int ANGLE_BRACKET_TAG_SYNTAX
        For example <#if x><@foo /></#if>
        See Also:
        Constant Field Values
      • LEGACY_INTERPOLATION_SYNTAX

        public static final int LEGACY_INTERPOLATION_SYNTAX
        ${expression} and the deprecated #{expression; numFormat} @since 2.3.28
        See Also:
        Constant Field Values
      • DOLLAR_INTERPOLATION_SYNTAX

        public static final int DOLLAR_INTERPOLATION_SYNTAX
        ${expression} only (not #{expression; numFormat}) @since 2.3.28
        See Also:
        Constant Field Values
      • SQUARE_BRACKET_INTERPOLATION_SYNTAX

        public static final int SQUARE_BRACKET_INTERPOLATION_SYNTAX
        [=expression] instead of ${expression}. It does not change <#if x> to [#if x]; that's square bracket tag syntax (SQUARE_BRACKET_TAG_SYNTAX).
        Since:
        2.3.28
        See Also:
        Constant Field Values
      • AUTO_DETECT_NAMING_CONVENTION

        public static final int AUTO_DETECT_NAMING_CONVENTION
        See Also:
        Constant Field Values
      • LEGACY_NAMING_CONVENTION

        public static final int LEGACY_NAMING_CONVENTION
        See Also:
        Constant Field Values
      • CAMEL_CASE_NAMING_CONVENTION

        public static final int CAMEL_CASE_NAMING_CONVENTION
        See Also:
        Constant Field Values
      • DISABLE_AUTO_ESCAPING_POLICY

        public static final int DISABLE_AUTO_ESCAPING_POLICY
        Don't enable auto-escaping, regardless of what the OutputFormat is. Note that a <#ftl auto_esc=true> in the template will override this.
        See Also:
        Constant Field Values
      • ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY

        public static final int ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY
        Enable auto-escaping if the OutputFormat supports it.
        See Also:
        Constant Field Values
      • DEFAULT_INCOMPATIBLE_ENHANCEMENTS

        @Deprecated
        public static final java.lang.String DEFAULT_INCOMPATIBLE_ENHANCEMENTS
        Deprecated.
      • PARSED_DEFAULT_INCOMPATIBLE_ENHANCEMENTS

        @Deprecated
        public static final int PARSED_DEFAULT_INCOMPATIBLE_ENHANCEMENTS
        Deprecated.
    • Constructor Detail

      • Configuration

        public Configuration​(Version incompatibleImprovements)
        Creates a new instance and sets which of the non-backward-compatible bugfixes/improvements should be enabled. Note that the specified versions corresponds to the incompatible_improvements configuration setting, and can be changed later, with setIncompatibleImprovements(Version) for example.

        About the "incompatible improvements" setting

        This setting value is the FreeMarker version number where the not 100% backward compatible bug fixes and improvements that you want to enable were already implemented. In new projects you should set this to the fixed FreeMarker version that you start the development with. In older projects it's also usually better to keep this high, however you should check the changes activated (find them below), especially if not only the 3rd version number (the micro version) of incompatibleImprovements is increased. Generally, as far as you only increase the last version number of this setting, the changes are low risk. The default value is 2.3.0 to maximize backward compatibility, but that value isn't recommended.

        Bugfixes and improvements that are fully backward compatible, also those that are important security fixes, are enabled regardless of the incompatible improvements setting.

        Do NOT ever use getVersion() to set the "incompatible improvements". Always use a fixed value, like VERSION_2_3_30. Otherwise your application can break as you upgrade FreeMarker. (As of 2.3.30, doing this will be logged as an error. As of 2.4.0, it will be probably disallowed, by throwing exception.)

        An important consequence of setting this setting is that now your application will check if the stated minimum FreeMarker version requirement is met. Like if you set this setting to 2.3.22, but accidentally the application is deployed with FreeMarker 2.3.21, then FreeMarker will fail, telling that a higher version is required. After all, the fixes/improvements you have requested aren't available on a lower version.

        Note that as FreeMarker's minor (2nd) or major (1st) version number increments, it's possible that emulating some of the old bugs will become unsupported, that is, even if you set this setting to a low value, it silently wont bring back the old behavior anymore. Information about that will be present here.

        Currently the effects of this setting are:

        • 2.3.0: This is the lowest supported value, the version used in very old projects. This is the default in the FreeMarker 2.3.x series (the one used by the deprecated Configuration() constructor) for maximum backward compatibility.

        • 2.3.19 (or higher): Bug fix: Wrong # tags were printed as static text instead of causing parsing error when there was no correct # or @ tag earlier in the same template.

        • 2.3.20 (or higher): ?html will escape apostrophe-quotes just like ?xhtml does. Utilizing this is highly recommended, because otherwise if interpolations are used inside attribute values that use apostrophe-quotation (<foo bar='${val}'>) instead of plain quotation mark (<foo bar="${val}">), they might produce HTML/XML that's not well-formed. Note that ?html didn't do this because long ago there was no cross-browser way of doing this, but it's not a concern anymore.

        • 2.3.21 (or higher):

          • The default of the object_wrapper setting (Configurable.getObjectWrapper()) changes from ObjectWrapper.DEFAULT_WRAPPER to another almost identical DefaultObjectWrapper singleton, returned by DefaultObjectWrapperBuilder.build(). The new default object wrapper's "incompatible improvements" version is set to the same as of the Configuration. See BeansWrapper(Version) for further details. Furthermore, the new default object wrapper doesn't allow changing its settings; setter methods throw IllegalStateException). (If anything tries to call setters on the old default in your application, that's a dangerous bug that won't remain hidden now. As the old default is a singleton too, potentially shared by independently developed components, most of them expects the out-of-the-box behavior from it (and the others are necessarily buggy). Also, then concurrency glitches can occur (and even pollute the class introspection cache) because the singleton is modified after publishing to other threads.) Furthermore the new default object wrapper shares class introspection cache with other BeansWrapper-s created with BeansWrapperBuilder, which has an impact as BeansWrapper.clearClassIntrospectionCache() will be disallowed; see more about it there.

          • The ?iso_... built-ins won't show the time zone offset for Time values anymore, because most databases store time values that aren't in any time zone, but just store hour, minute, second, and decimal second field values. If you still want to show the offset (like for PostgreSQL "time with time zone" columns you should), you can force showing the time zone offset by using myTime?string.iso_fz (and its other variants).

          • ?is_enumerable correctly returns false for Java methods get from Java objects that are wrapped with BeansWrapper and its subclasses, like DefaultObjectWrapper. Although method values implement TemplateSequenceModel (because of a historical design quirk in BeansWrapper), trying to #list them will cause error, hence they aren't enumerable.

          • ?c will return "INF", "-INF" and "NaN" for positive/negative infinity and IEEE floating point Not-a-Number, respectively. These are the XML Schema compatible representations of these special values. Earlier it has returned what DecimalFormat did with US locale, none of which was understood by any (common) computer language.

          • FTL hash literals that repeat keys now only have the key once with ?keys, and only has the last value associated to that key with ?values. This is consistent with the behavior of hash[key] and how maps work in Java.

          • In most cases (where FreeMarker is able to do that), for TemplateLoader-s that use URLConnection, URLConnection#setUseCaches(boolean) will called with false, so that only FreeMarker will do caching, not the URL scheme's handler. See URLTemplateLoader.setURLConnectionUsesCaches(Boolean) for more details.

          • The default of the template_loader setting (getTemplateLoader()) changes to null, which means that FreeMarker will not find any templates. Earlier the default was a FileTemplateLoader that used the current directory as the root. This was dangerous and fragile as you usually don't have good control over what the current directory will be. Luckily, the old default almost never looked for the templates at the right place anyway, so pretty much all applications had to set the template_loader setting, so it's unlikely that changing the default breaks your application.

          • Right-unlimited ranges become readable (like listable), so <#list 1.. as i>...</#list> works. Earlier they were only usable for slicing (like hits[10..]).

          • Empty ranges return Constants.EMPTY_SEQUENCE instead of an empty SimpleSequence. This is in theory backward compatible, as the API only promises to give something that implements TemplateSequenceModel.

          • Unclosed comments (<#-- ...) and #noparse-s won't be silently closed at the end of template anymore, but cause a parsing error instead.

        • 2.3.22 (or higher):

          • DefaultObjectWrapper has some substantial changes with incompatibleImprovements 2.3.22; check them out at DefaultObjectWrapper(Version). It's important to know that if you set the object_wrapper setting (to an other value than "default"), rather than leaving it on its default value, the object_wrapper won't inherit the incompatibleImprovements of the Configuration. In that case, if you want the 2.3.22 improvements of DefaultObjectWrapper, you have to set it in the DefaultObjectWrapper object itself too! (Note that it's OK to use a DefaultObjectWrapper with a different incompatibleImprovements version number than that of the Configuration, if that's really what you want.)

          • In templates, .template_name will always return the main (top level) template's name. It won't be affected by #include and #nested anymore. This is unintended, a bug with incompatible_improvement 2.3.22 (a consequence of the lower level fixing described in the next point). The old behavior of .template_name is restored if you set incompatible_improvement to 2.3.23 (while Configurable.getParent()) of Environment keeps the changed behavior shown in the next point).

          • #include and #nested doesn't change the parent Template (see Configurable.getParent()) of the Environment anymore to the Template that's included or whose namespace #nested "returns" to. Thus, the parent of Environment will be now always the main Template. (The main Template is the Template whose process or createProcessingEnvironment method was called to initiate the output generation.) Note that apart from the effect on FTL's .template_name (see previous point), this should only matter if you have set settings directly on Template objects, and almost nobody does that. Also note that macro calls have never changed the Environment parent to the Template that contains the macro definition, so this mechanism was always broken. As now we consistently never change the parent, the behavior when calling macros didn't change.

          • When using freemarker.ext.servlet.FreemarkerServlet:

            • When using custom JSP tag libraries: Fixes bug where some kind of values, when put into the JSP page scope (via #global or via the JSP PageContext API) and later read back with the JSP PageContext API (typically in a custom JSP tag), might come back as FreeMarker TemplateModel objects instead of as objects with a standard Java type. Other Servlet scopes aren't affected. It's highly unlikely that something expects the presence of this bug. The affected values are of the FTL types listed below, and to trigger the bug, they either had to be created directly in the template (like as an FTL literal or with ?date/time/datetime), or you had to use DefaultObjectWrapper or SimpleObjectWrapper (or a subclass of them):

              • FTL date/time/date-time values may came back as SimpleDate-s, now they come back as java.util.Date-s instead.
              • FTL sequence values may came back as SimpleSequence-s, now they come back as List-s as expected. This at least stands assuming that the object_wrapper configuration setting is a subclass of BeansWrapper (such as DefaultObjectWrapper, which is the default), but that's practically always the case in applications that use FreeMarker's JSP extension (otherwise it can still work, but it depends on the quality and capabilities of the ObjectWrapper implementation).
              • FTL hash values may came back as SimpleHash-es, now they come back as Map-s as expected (again, assuming that the object wrapper is a subclass of BeansWrapper, like preferably DefaultObjectWrapper, which is also the default).
              • FTL collection values may came back as SimpleCollection-s, now they come back as Collection-s as expected (again, assuming that the object wrapper is a subclass of BeansWrapper, like preferably DefaultObjectWrapper).
            • Initial "[" in the TemplatePath init-param has special meaning; it's used for specifying multiple comma separated locations, like in <param-value>[ WEB-INF/templates, classpath:com/example/myapp/templates ]</param-value>

            • Initial "{" in the TemplatePath init-param is reserved for future purposes, and thus will throw exception.

        • 2.3.23 (or higher):

          • Fixed a loophole in the implementation of the long existing parse-time rule that says that #break, in the FTL source code itself, must occur nested inside a breakable directive, such as #list or #switch. This check could be circumvented with #macro or #function, like this: <#list 1..1 as x><#macro callMeLater><#break></#macro></#list><@callMeLater />. After activating this fix, this will be a parse time error.

          • If you have used incompatible_improvements 2.3.22 earlier, know that there the behavior of the .template_name special variable used in templates was accidentally altered, but now it's restored to be backward compatible with 2.3.0. (Ironically, the restored legacy behavior itself is broken when it comes to macro invocations, we just keep it for backward compatibility. If you need fixed behavior, use .current_template_name or .main_template_name instead.)

        • 2.3.24 (or higher):

          • The default of the recognize_standard_file_extensions setting changes to true, which means that templates whose name ends with ".ftlh" or ".ftlx" will automatically get HTMLOutputFormat.INSTANCE or XMLOutputFormat.INSTANCE output format respectively, in both cases with ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY auto_escaping_policy. These "file" extensions aren't case sensitive.

          • In number format and date format strings (like in the number_format setting, or in templates in n?string("0.##")), an initial '@' has special meaning; they refer to a custom format with the name given after the @ (see: Configurable.setCustomNumberFormats(Map), Configurable.setCustomDateFormats(Map), Configurable.setNumberFormat(String), and Configurable.setDateTimeFormat(java.lang.String)). If the custom format doesn't exist, that will be an error. To have a literal @ as the first character in the output, it has to be written as @@. Again, all this only applies to the very first character of the format string, so @ characters elsewhere must not be doubled. Also, if there are any custom formats defined, initial '@' will have the new meaning regardless of the value of the incompatible_improvements setting. So you don't need to set the incompatible_improvements only to use custom formats.

          • Expressions inside interpolations that were inside string literal expressions (not ${...}-s in general), like in <#assign s="Hello ${name}!">, has always used incompatbileImprovement-s 0 (2.3.0 in effect). Now it's fixed.

          • DefaultObjectWrapper has some minor changes with incompatibleImprovements 2.3.24; check them out at DefaultObjectWrapper(Version). It's important to know that if you set the object_wrapper setting (to an other value than "default"), rather than leaving it on its default value, the object_wrapper won't inherit the incompatibleImprovements of the Configuration. In that case, if you want the 2.3.24 improvements of DefaultObjectWrapper, you have to set it in the DefaultObjectWrapper object itself too! (Note that it's OK to use a DefaultObjectWrapper with a different incompatibleImprovements version number than that of the Configuration, if that's really what you want.)

          • Fixed bug: The #import directive meant to copy the library variable into a global variable if it's executed in the main namespace, but that haven't happened when the imported template was already imported earlier in another namespace.

          • ?is_sequence doesn't return true for Java methods wrapped by BeansWrapper and its subclasses (most notably DefaultObjectWrapper) anymore, as they only implement the [index] operator, but not ?size, which causes <#list ...> to fail among others. (They shouldn't implement either, but this is historical heritage.)

        • 2.3.25 (or higher):

        • 2.3.26 (or higher):

        • 2.3.27 (or higher):

          • BeansWrapper and DefaultObjectWrapper now prefers the non-indexed JavaBean property read method over the indexed read method when Java 8 exposes both; see BeansWrapper(Version).

          • The following unchecked exceptions (but not their subclasses) will be wrapped into TemplateException-s when thrown during evaluating expressions or calling directives: NullPointerException, ClassCastException, IndexOutOfBoundsException, and InvocationTargetException. The goal of this is the same as of setting wrap_unchecked_exceptions to true (see more there), but this is more backward compatible, as it avoids wrapping unchecked exceptions that the calling application is likely to catch specifically (like application-specific unchecked exceptions).

          • When the Writer returned by TemplateTransformModel.getWriter(Writer, Map) implements TransformControl, exceptions that are used internally by FreeMarker for flow control (for <#return>, <#break>, etc.) won't be passed to TransformControl.onError(Throwable) anymore. Earlier, if onError didn't rethrow the exception (though almost all implementation does), you couldn't use said directives inside the transformed block. It's very unlikely that user code is affected by this, partially because these aren't commonly implemented interfaces (especially not TransformControl), and because it's unlikely that templates utilize the the bug that's not fixed.

        • 2.3.28 (or higher):

          • When calling a macro or function (things defined in a template, not directly in Java) and the argument list contains .current_template_name, now it will correctly evaluate to the template that contains the call, rather than to the template that contains the macro or function definition. (Of course, the parameter default value expression is still evaluated in the context of the called macro or function.) Similarly, .macro_caller_template_name (which itself was added in 2.3.28), when used in a macro call argument, won't be incorrectly evaluated in the context of the called macro.

          • Fixed legacy parser glitch where a tag can be closed with an illegal ] (when it's not part of an expression) despite that the tag syntax is set to angle brackets. For example <#if x] worked just like <#if x>. Note that it doesn't affect the legal usage of ], like <#if x[0]> works correctly without this fix as well.

        • 2.3.31 (or higher):

          • When you set the number_format setting to "computer" (or you call Environment.getCNumberFormat()), the format now matches the behavior of ?c, when formatting infinite (positive and negative), and NaN. Matching the behavior of ?c was always the intent, but before this incompatible improvement, the "computer" format always behaved like ?c before Incompatible Improvements 2.3.21, where instead of INF, and NaN, the results used unicode characters U+221E, and U+FFFD.

        Throws:
        java.lang.IllegalArgumentException - If incompatibleImmprovements refers to a version that wasn't released yet when the currently used FreeMarker version was released, or is less than 2.3.0, or is null.
        Since:
        2.3.21
    • Method Detail

      • loadBuiltInEncodingMap

        public void loadBuiltInEncodingMap()
        Loads a preset language-to-encoding map, similarly as if you have called clearEncodingMap() and then did multiple setEncoding(Locale, String) calls. It assumes the usual character encodings for most languages. The previous content of the encoding map will be lost. This default map currently contains the following mappings:
        arISO-8859-6
        beISO-8859-5
        bgISO-8859-5
        caISO-8859-1
        csISO-8859-2
        daISO-8859-1
        deISO-8859-1
        elISO-8859-7
        enISO-8859-1
        esISO-8859-1
        etISO-8859-1
        fiISO-8859-1
        frISO-8859-1
        hrISO-8859-2
        huISO-8859-2
        isISO-8859-1
        itISO-8859-1
        iwISO-8859-8
        jaShift_JIS
        koEUC-KR
        ltISO-8859-2
        lvISO-8859-2
        mkISO-8859-5
        nlISO-8859-1
        noISO-8859-1
        plISO-8859-2
        ptISO-8859-1
        roISO-8859-2
        ruISO-8859-5
        shISO-8859-5
        skISO-8859-2
        slISO-8859-2
        sqISO-8859-2
        srISO-8859-5
        svISO-8859-1
        trISO-8859-9
        ukISO-8859-5
        zhGB2312
        zh_TWBig5
        See Also:
        clearEncodingMap(), setEncoding(Locale, String), setDefaultEncoding(String)
      • getDefaultConfiguration

        @Deprecated
        public static Configuration getDefaultConfiguration()
        Deprecated.
        The usage of the static singleton (the "default") Configuration instance can easily cause erroneous, unpredictable behavior. This is because multiple independent software components may use FreeMarker internally inside the same application, so they will interfere because of the common Configuration instance. Each such component should use its own private Configuration object instead, that it typically creates with new Configuration() when the component is initialized.
        Returns the default (singleton) Configuration object. Note that you can create as many separate configurations as you wish; this global instance is provided for convenience, or when you have no reason to use a separate instance.
      • setDefaultConfiguration

        @Deprecated
        public static void setDefaultConfiguration​(Configuration config)
        Deprecated.
        Using the "default" Configuration instance can easily lead to erroneous, unpredictable behaviour. See more here....
        Sets the Configuration object that will be retrieved from future calls to getDefaultConfiguration().
      • unsetTemplateLoader

        public void unsetTemplateLoader()
        Resets the setting to its default, as if it was never set. This means that when you change the incompatibe_improvements setting later, the default will also change as appropriate. Also isTemplateLoaderExplicitlySet() will return false.
        Since:
        2.3.22
      • isTemplateLoaderExplicitlySet

        public boolean isTemplateLoaderExplicitlySet()
        Tells if setTemplateLoader(TemplateLoader) (or equivalent) was already called on this instance.
        Since:
        2.3.22
      • unsetTemplateLookupStrategy

        public void unsetTemplateLookupStrategy()
        Resets the setting to its default, as if it was never set. This means that when you change the incompatibe_improvements setting later, the default will also change as appropriate. Also isTemplateLookupStrategyExplicitlySet() will return false.
        Since:
        2.3.22
      • unsetTemplateNameFormat

        public void unsetTemplateNameFormat()
        Resets the setting to its default, as if it was never set. This means that when you change the incompatibe_improvements setting later, the default will also change as appropriate. Also isTemplateNameFormatExplicitlySet() will return false.
        Since:
        2.3.22
      • isTemplateNameFormatExplicitlySet

        public boolean isTemplateNameFormatExplicitlySet()
        Tells if setTemplateNameFormat(TemplateNameFormat) (or equivalent) was already called on this instance.
        Since:
        2.3.22
      • setTemplateConfigurations

        public void setTemplateConfigurations​(TemplateConfigurationFactory templateConfigurations)
        Sets a TemplateConfigurationFactory that will configure individual templates where their settings differ from those coming from the common Configuration object. A typical use case for that is specifying the outputFormat for templates based on their file extension or parent directory.

        Note that the settings suggested by standard file extensions are stronger than that you set here. See setRecognizeStandardFileExtensions(boolean) for more information about standard file extensions.

        See "Template configurations" in the FreeMarker Manual for examples.

        Since:
        2.3.24
      • setCacheStorage

        public void setCacheStorage​(CacheStorage cacheStorage)
        Sets the CacheStorage used for caching Template-s; the earlier content of the template cache will be dropt. The default is a SoftCacheStorage. If the total size of the Template objects is significant but most templates are used rarely, using a MruCacheStorage instead might be advisable. If you don't want caching at all, use NullCacheStorage (you can't use null).

        Note that setting the cache storage will re-create the template cache, so all its content will be lost.

      • unsetCacheStorage

        public void unsetCacheStorage()
        Resets the setting to its default, as if it was never set. This means that when you change the incompatibe_improvements setting later, the default will also change as appropriate. Also isCacheStorageExplicitlySet() will return false.
        Since:
        2.3.22
      • isCacheStorageExplicitlySet

        public boolean isCacheStorageExplicitlySet()
        Tells if setCacheStorage(CacheStorage) (or equivalent) was already called on this instance.
        Since:
        2.3.22
      • setDirectoryForTemplateLoading

        public void setDirectoryForTemplateLoading​(java.io.File dir)
                                            throws java.io.IOException
        Sets the file system directory from which to load templates. This is equivalent to setTemplateLoader(new FileTemplateLoader(dir)), so see FileTemplateLoader(File) for more details.

        Note that FreeMarker can load templates from non-file-system sources too. See setTemplateLoader(TemplateLoader) from more details.

        Note that this shouldn't be used for loading templates that are coming from a WAR; use setServletContextForTemplateLoading(Object, String) then. Servlet containers might not unpack the WAR file, in which case you clearly can't access the contained files via File. Even if the WAR is unpacked, the servlet container might not expose the location as a File. setServletContextForTemplateLoading(Object, String) on the other hand will work in all these cases.

        Throws:
        java.io.IOException
      • setServletContextForTemplateLoading

        public void setServletContextForTemplateLoading​(java.lang.Object servletContext,
                                                        java.lang.String path)
        Sets the servlet context from which to load templates. This is equivalent to setTemplateLoader(new WebappTemplateLoader(sctxt, path)) or setTemplateLoader(new WebappTemplateLoader(sctxt)) if path was null, so see freemarker.cache.WebappTemplateLoader for more details.
        Parameters:
        servletContext - the javax.servlet.ServletContext object. (The declared type is Object to prevent class loading error when using FreeMarker in an environment where there's no servlet classes available.)
        path - the path relative to the ServletContext.
        See Also:
        setTemplateLoader(TemplateLoader)
      • setTemplateUpdateDelay

        @Deprecated
        public void setTemplateUpdateDelay​(int seconds)
        Deprecated.
        Use setTemplateUpdateDelayMilliseconds(long) instead, because the time granularity of this method is often misunderstood to be milliseconds.
        Sets the time in seconds that must elapse before checking whether there is a newer version of a template "file" than the cached one.

        Historical note: Despite what the API documentation said earlier, this method is not thread-safe. While it works well on most hardware, it's not guaranteed that FreeMarker will see the update in all threads, and theoretically it's also possible that it will see a value that's a binary mixture of the new and the old one.

      • setTemplateUpdateDelayMilliseconds

        public void setTemplateUpdateDelayMilliseconds​(long millis)
        Sets the time in milliseconds that must elapse before checking whether there is a newer version of a template "file" than the cached one. Defaults to 5000 ms.

        When you get a template via getTemplate(String) (or some of its overloads). FreeMarker will try to get the template from the template cache. If the template is found, and at least this amount of time was elapsed since the template last modification date was checked, FreeMarker will re-check the last modification date (this could mean I/O), possibly reloading the template and updating the cache as a consequence (can mean even more I/O). The getTemplate(String) (or some of its overloads) call will only return after this all is done, so it will return the fresh template.

        Since:
        2.3.23
      • setStrictSyntaxMode

        @Deprecated
        public void setStrictSyntaxMode​(boolean b)
        Deprecated.
        Only true (the default) value will be supported sometimes in the future.
        Sets whether directives such as if, else, etc must be written as #if, #else, etc. Defaults to true.

        When this is true, any tag not starting with <# or </# or <@ or </@ is considered as plain text and will go to the output as is. Tag starting with <# or </# must be valid FTL tag, or else the template is invalid (i.e. <#noSuchDirective> is an error).

      • unsetObjectWrapper

        public void unsetObjectWrapper()
        Resets the setting to its default, as if it was never set. This means that when you change the incompatibe_improvements setting later, the default will also change as appropriate. Also isObjectWrapperExplicitlySet() will return false.
        Since:
        2.3.22
      • isObjectWrapperExplicitlySet

        public boolean isObjectWrapperExplicitlySet()
        Tells if setObjectWrapper(ObjectWrapper) (or equivalent) was already called on this instance.
        Since:
        2.3.22
      • setLocale

        public void setLocale​(java.util.Locale locale)
        Description copied from class: Configurable
        Sets the locale used for number and date formatting (among others), also the locale used for searching localized template variations when no locale was explicitly requested. On the Configuration level it defaults to the default locale of system (of the JVM), for server-side application usually you should set it explicitly in the Configuration to use the preferred locale of your application instead.
        Overrides:
        setLocale in class Configurable
        See Also:
        getTemplate(String, Locale)
      • unsetLocale

        public void unsetLocale()
        Resets the setting to its default, as if it was never set.
        Since:
        2.3.26
      • isLocaleExplicitlySet

        public boolean isLocaleExplicitlySet()
        Tells if setLocale(Locale) (or equivalent) was already called on this instance, or it just holds the default value.
        Since:
        2.3.26
      • unsetTimeZone

        public void unsetTimeZone()
        Resets the setting to its default, as if it was never set.
        Since:
        2.3.26
      • isTimeZoneExplicitlySet

        public boolean isTimeZoneExplicitlySet()
        Tells if setTimeZone(TimeZone) (or equivalent) was already called on this instance, or it just holds the default value.
        Since:
        2.3.26
      • unsetTemplateExceptionHandler

        public void unsetTemplateExceptionHandler()
        Resets the setting to its default, as if it was never set. This means that when you change the incompatibe_improvements setting later, the default will also change as appropriate. Also isTemplateExceptionHandlerExplicitlySet() will return false.
        Since:
        2.3.22
      • unsetAttemptExceptionReporter

        public void unsetAttemptExceptionReporter()
        Resets the setting to its default, as if it was never set. This means that when you change the incompatibe_improvements setting later, the default will also change as appropriate. Also isAttemptExceptionReporterExplicitlySet() will return false.
        Since:
        2.3.27
      • setLogTemplateExceptions

        public void setLogTemplateExceptions​(boolean value)
        Specifies if TemplateException-s thrown by template processing are logged by FreeMarker or not. The default is true for backward compatibility, but that results in logging the exception twice in properly written applications, because there the TemplateException thrown by the public FreeMarker API is also logged by the caller (even if only as the cause exception of a higher level exception). Hence, in modern applications it should be set to false. Note that this setting has no effect on the logging of exceptions caught by #attempt; by default those are always logged as errors (because those exceptions won't bubble up to the API caller), however, that can be changed with the attempt_exception_reporter setting.
        Overrides:
        setLogTemplateExceptions in class Configurable
        Since:
        2.3.22
      • unsetLogTemplateExceptions

        public void unsetLogTemplateExceptions()
        Resets the setting to its default, as if it was never set. This means that when you change the incompatibe_improvements setting later, the default will also change as appropriate. Also isTemplateExceptionHandlerExplicitlySet() will return false.
        Since:
        2.3.22
      • isLogTemplateExceptionsExplicitlySet

        public boolean isLogTemplateExceptionsExplicitlySet()
        Tells if setLogTemplateExceptions(boolean) (or equivalent) was already called on this instance.
        Since:
        2.3.22
      • setWrapUncheckedExceptions

        public void setWrapUncheckedExceptions​(boolean value)
        Specifies if unchecked exceptions thrown during expression evaluation or during executing custom directives (and transform) will be wrapped into TemplateException-s, or will bubble up to the caller of Template.process(Object, Writer, ObjectWrapper) as is. The default is false for backward compatibility (as some applications catch certain unchecked exceptions thrown by the template processing to do something special), but the recommended value is true. When this is true, the unchecked exceptions will be wrapped into a TemplateException-s, thus the exception will include the location in the template (not just the Java stack trace). Another consequence of the wrapping is that the TemplateExceptionHandler will be invoked for the exception (as that only handles TemplateException-s, it wasn't invoked for unchecked exceptions). When this setting is false, unchecked exception will be thrown by Template.process(Object, Writer, ObjectWrapper). Note that plain Java methods called from templates aren't user defined TemplateMethodModel-s, and have always wrapped the thrown exception into TemplateException, regardless of this setting.
        Overrides:
        setWrapUncheckedExceptions in class Configurable
        Since:
        2.3.27
      • unsetWrapUncheckedExceptions

        public void unsetWrapUncheckedExceptions()
        Since:
        2.3.27
      • isWrapUncheckedExceptionsExplicitlySet

        public boolean isWrapUncheckedExceptionsExplicitlySet()
        Tells if setWrapUncheckedExceptions(boolean) (or equivalent) was already called on this instance.
        Since:
        2.3.27
      • setIncompatibleImprovements

        public void setIncompatibleImprovements​(Version incompatibleImprovements)
        Use Configuration(Version) instead if possible; see the meaning of the parameter there.

        Do NOT ever use getVersion() to set the "incompatible improvements". Always use a fixed value, like VERSION_2_3_30. Otherwise your application can break as you upgrade FreeMarker. (As of 2.3.30, doing this will be logged as an error. As of 2.4.0, it will be probably disallowed, by throwing exception.)

        If the default value of a setting depends on the incompatibleImprovements and the value of that setting was never set in this Configuration object through the public API, its value will be set to the default value appropriate for the new incompatibleImprovements. (This adjustment of a setting value doesn't count as setting that setting, so setting incompatibleImprovements for multiple times also works as expected.) Note that if the template_loader have to be changed because of this, the template cache will be emptied.

        Throws:
        java.lang.IllegalArgumentException - If incompatibleImmprovements refers to a version that wasn't released yet when the currently used FreeMarker version was released, or is less than 2.3.0, or is null.
        Since:
        2.3.20
      • getIncompatibleEnhancements

        @Deprecated
        public java.lang.String getIncompatibleEnhancements()
        Deprecated.
      • getParsedIncompatibleEnhancements

        @Deprecated
        public int getParsedIncompatibleEnhancements()
        Deprecated.
      • setWhitespaceStripping

        public void setWhitespaceStripping​(boolean b)
        Sets whether the FTL parser will try to remove superfluous white-space around certain FTL tags.
      • isOutputFormatExplicitlySet

        public boolean isOutputFormatExplicitlySet()
        Tells if setOutputFormat(OutputFormat) (or equivalent) was already called on this instance.
        Since:
        2.3.24
      • unsetOutputFormat

        public void unsetOutputFormat()
        Resets the setting to its default, as if it was never set. This means that when you change the incompatibe_improvements setting later, the default will also change as appropriate. Also isOutputFormatExplicitlySet() will return false.
        Since:
        2.3.24
      • getOutputFormat

        public OutputFormat getOutputFormat​(java.lang.String name)
                                     throws UnregisteredOutputFormatException
        Returns the output format for a name.
        Parameters:
        name - Either the name of the output format as it was registered with setRegisteredCustomOutputFormats(Collection), or a combined output format name. A combined output format is created ad-hoc from the registered formats. For example, if you need RTF embedded into HTML, the name will be HTML{RTF}, where "HTML" and "RTF" refer to the existing formats. This logic can be used recursively, so for example XML{HTML{RTF}} is also valid.
        Returns:
        Not null.
        Throws:
        UnregisteredOutputFormatException - If there's no output format registered with the given name.
        java.lang.IllegalArgumentException - If the usage of { and } in the name is syntactically wrong, or if not all OutputFormat-s are MarkupOutputFormat-s in the ...{...} expression.
        Since:
        2.3.24
      • unsetRecognizeStandardFileExtensions

        public void unsetRecognizeStandardFileExtensions()
        Resets the setting to its default, as if it was never set. This means that when you change the incompatibe_improvements setting later, the default will also change as appropriate. Also isRecognizeStandardFileExtensionsExplicitlySet() will return false.
        Since:
        2.3.24
      • isRecognizeStandardFileExtensionsExplicitlySet

        public boolean isRecognizeStandardFileExtensionsExplicitlySet()
        Tells if setRecognizeStandardFileExtensions(boolean) (or equivalent) was already called on this instance.
        Since:
        2.3.24
      • setTagSyntax

        public void setTagSyntax​(int tagSyntax)
        Determines the tag syntax (like <#if x> VS [#if x]) of the template files that has no #ftl header to decide that. Don't confuse this with the interpolation syntax (setInterpolationSyntax(int)); they are independent.

        The tagSyntax parameter must be one of:

        In FreeMarker 2.3.x ANGLE_BRACKET_TAG_SYNTAX is the default for better backward compatibility. Starting from 2.4.x AUTO_DETECT_TAG_SYNTAX is the default, so it's recommended to use that even for 2.3.x.

        This setting is ignored for the templates that have ftl directive in it. For those templates the syntax used for the ftl directive determines the syntax.

        See Also:
        setInterpolationSyntax(int)
      • setNamingConvention

        public void setNamingConvention​(int namingConvention)
        Sets the naming convention used for the identifiers that are part of the template language. The available naming conventions are legacy (directive (tag) names are all-lower-case likethis, others are snake case like_this), and camel case (likeThis). The default is auto-detect, which detects the naming convention used and enforces that same naming convention for the whole template.

        This setting doesn't influence what naming convention is used for the setting names outside templates. Also, it won't ever convert the names of user-defined things, like of data-model members, or the names of user defined macros/functions. It only influences the names of the built-in directives (#elseIf VS elseif), built-ins (?upper_case VS ?upperCase ), special variables (.data_model VS .dataModel).

        Which convention to use: FreeMarker prior to 2.3.23 has only supported LEGACY_NAMING_CONVENTION, so that's how most templates and examples out there are written as of 2015. But as templates today are mostly written by programmers and often access Java API-s which already use camel case, CAMEL_CASE_NAMING_CONVENTION is the recommended option for most projects. However, it's no necessary to make a application-wide decision; see auto-detection below.

        FreeMarker will decide the naming convention automatically for each template individually when this setting is set to AUTO_DETECT_NAMING_CONVENTION (which is the default). The naming convention of a template is decided when the first core (non-user-defined) identifier is met during parsing (not during processing) where the naming convention is relevant (like for s?upperCase or s?upper_case it's relevant, but for s?length it isn't). At that point, the naming convention of the template is decided, and any later core identifier that uses a different convention will be a parsing error. As the naming convention is decided per template, it's not a problem if a template and the other template it #include-s/#import uses a different convention.

        FreeMarker always enforces the same naming convention to be used consistently within the same template "file". Additionally, when this setting is set to non-AUTO_DETECT_NAMING_CONVENTION, the selected naming convention is enforced on all templates. Thus such a setup can be used to enforce an application-wide naming convention.

        Non-strict tags (a long deprecated syntax from FreeMarker 1, activated via setStrictSyntaxMode(boolean)) are only recognized as FTL tags when they are using the LEGACY_NAMING_CONVENTION syntax, regardless of this setting. As they aren't exempt from the naming convention consistency enforcement, generally, you can't use strict CAMEL_CASE_NAMING_CONVENTION tags mixed with non-strict tags.

        Parameters:
        namingConvention - One of the AUTO_DETECT_NAMING_CONVENTION or LEGACY_NAMING_CONVENTION CAMEL_CASE_NAMING_CONVENTION.
        Throws:
        java.lang.IllegalArgumentException - If the parameter isn't one of the valid constants.
        Since:
        2.3.23
      • setTabSize

        public void setTabSize​(int tabSize)
        Sets the assumed display width of the tab character (ASCII 9), which influences the column number shown in error messages (or the column number you get through other API-s). So for example if the users edit templates in an editor where the tab width is set to 4, you should set this to 4 so that the column numbers printed by FreeMarker will match the column number shown in the editor. This setting doesn't affect the output of templates, as a tab in the template will remain a tab in the output too. If you set this setting to 1, then tab characters will be kept in the return value of Template.getSource(int, int, int, int), otherwise they will be replaced with the appropriate number of spaces.
        Parameters:
        tabSize - At least 1, at most 256.
        Since:
        2.3.25
      • setFallbackOnNullLoopVariable

        public void setFallbackOnNullLoopVariable​(boolean fallbackOnNullLoopVariable)
        Specifies the behavior when reading a loop variable (like i in <#list items as i>, or in <@myMacro items; i>) that's null (missing); if true, FreeMarker will look for a variable with the same name in higher variable scopes, or if false the variable will be simply null (missing). For backward compatibility the default is true. The recommended value for new projects is false, as otherwise adding new variables to higher scopes (typically to the data-model) can unintentionally change the behavior of templates. You have to be quite unlucky for that to happen though: The newly added variable has to have the same name as the loop variable, and there must be some null (missing) values in what you loop through.

        This setting doesn't influence the behavior of lambdas, like items?filter(i -> i?hasContent), as they never had this problem. Reading a lambda argument never falls back to higher scopes.

        Since:
        2.3.29
      • getTemplate

        public Template getTemplate​(java.lang.String name,
                                    java.util.Locale locale,
                                    java.lang.Object customLookupCondition,
                                    java.lang.String encoding,
                                    boolean parseAsFTL,
                                    boolean ignoreMissing)
                             throws TemplateNotFoundException,
                                    MalformedTemplateNameException,
                                    ParseException,
                                    java.io.IOException
        Retrieves the template with the given name (and according the specified further parameters) from the template cache, loading it into the cache first if it's missing/staled.

        This method is thread-safe.

        See Configuration for an example of basic usage.

        Parameters:
        name - The name or path of the template, which is not a real path, but interpreted inside the current TemplateLoader. Can't be null. The exact syntax of the name depends on the underlying TemplateLoader, but the cache makes some assumptions. First, the name is expected to be a hierarchical path, with path components separated by a slash character (not with backslash!). The path (the name) given here must not begin with slash; it's always interpreted relative to the "template root directory". Then, the .. and . path meta-elements will be resolved. For example, if the name is a/../b/./c.ftl, then it will be simplified to b/c.ftl. The rules regarding this are the same as with conventional UN*X paths. The path must not reach outside the template root directory, that is, it can't be something like "../templates/my.ftl" (not even if this path happens to be equivalent with "/my.ftl"). Furthermore, the path is allowed to contain at most one path element whose name is * (asterisk). This path meta-element triggers the acquisition mechanism. If the template is not found in the location described by the concatenation of the path left to the asterisk (called base path) and the part to the right of the asterisk (called resource path), the cache will attempt to remove the rightmost path component from the base path ("go up one directory") and concatenate that with the resource path. The process is repeated until either a template is found, or the base path is completely exhausted.
        locale - The requested locale of the template. This is what Configurable.getLocale() on the resulting Template will return (unless it's overridden via getTemplateConfigurations()). This parameter can be null since 2.3.22, in which case it defaults to Configurable.getLocale() (note that Configurable.getLocale() will give the default value, not null). This parameter also drives localized template lookup. Assuming that you have specified en_US as the locale and myTemplate.ftl as the name of the template, and the default TemplateLookupStrategy is used and #setLocalizedLookup(boolean) localized_lookup is true, FreeMarker will first try to retrieve myTemplate_en_US.html, then myTemplate.en.ftl, and finally myTemplate.ftl. Note that that the template's locale will be en_US even if it only finds myTemplate.ftl. Note that when the locale setting is overridden with a TemplateConfiguration provided by getTemplateConfigurations(), that overrides the value specified here, but only after the localized lookup, that is, it modifies the template found by the localized lookup.
        customLookupCondition - This value can be used by a custom TemplateLookupStrategy; has no effect with the default one. Can be null (though it's up to the custom TemplateLookupStrategy if it allows that). This object will be used as part of the cache key, so it must to have a proper Object.equals(Object) and Object.hashCode() method. It also should have reasonable Object.toString(), as it's possibly quoted in error messages. The expected type is up to the custom TemplateLookupStrategy. See also: TemplateLookupContext.getCustomLookupCondition().
        encoding - Deprecated mechanism, null is the recommended; the charset used to interpret the template source code bytes (if it's read from a binary source). Can be null since 2.3.22, in which case it will default to getEncoding(Locale) where Locale is the locale parameter (when locale was null too, the its default value is used instead). Why is this deprecated: It doesn't make sense to get the same template with different encodings, hence, it's error prone to specify the encoding where you get the template. Instead, if you have template "files" with different charsets, you should use setTemplateConfigurations(TemplateConfigurationFactory), where you can associate encodings to individual templates based on their names (like which "directory" are they in, what's their file extension, etc.). The encoding associated with the templates that way overrides the encoding that you specify here.
        parseAsFTL - If true, the loaded template is parsed and interpreted normally, as a regular FreeMarker template. If false, the loaded template is treated as a static text, so ${...}, <#...> etc. will not have special meaning in it.
        ignoreMissing - If true, the method won't throw TemplateNotFoundException if the template doesn't exist, instead it returns null. Other kind of exceptions won't be suppressed.
        Returns:
        the requested template; maybe null when the ignoreMissing parameter is true.
        Throws:
        TemplateNotFoundException - If the template could not be found. Note that this exception extends IOException.
        MalformedTemplateNameException - If the template name given was in violation with the TemplateNameFormat in use. Note that this exception extends IOException.
        ParseException - (extends IOException) if the template is syntactically bad. Note that this exception extends IOException.
        java.io.IOException - If there was some other problem with reading the template "file". Note that the other exceptions extend IOException, so this should be catched the last.
        Since:
        2.3.22
      • setDefaultEncoding

        public void setDefaultEncoding​(java.lang.String encoding)
        Sets the charset used for decoding byte sequences to character sequences when reading template files in a locale for which no explicit encoding was specified via setEncoding(Locale, String). Note that by default there is no locale specified for any locale, so the default encoding is always in effect.

        Defaults to the default system encoding, which can change from one server to another, so you should always set this setting. If you don't know what charset your should chose, "UTF-8" is usually a good choice.

        Note that individual templates may specify their own charset by starting with <#ftl encoding="...">

        Parameters:
        encoding - The name of the charset, such as "UTF-8" or "ISO-8859-1"
      • getDefaultEncoding

        public java.lang.String getDefaultEncoding()
        Gets the default encoding for converting bytes to characters when reading template files in a locale for which no explicit encoding was specified. Defaults to the default system encoding.
      • unsetDefaultEncoding

        public void unsetDefaultEncoding()
        Resets the setting to its default, as if it was never set.
        Since:
        2.3.26
      • isDefaultEncodingExplicitlySet

        public boolean isDefaultEncodingExplicitlySet()
        Tells if setDefaultEncoding(String) (or equivalent) was already called on this instance, or it just holds the default value.
        Since:
        2.3.26
      • getEncoding

        public java.lang.String getEncoding​(java.util.Locale locale)
        Gets the preferred character encoding for the given locale, or the default encoding if no encoding is set explicitly for the specified locale. You can associate encodings with locales using setEncoding(Locale, String) or loadBuiltInEncodingMap().
        Parameters:
        locale - Shouldn't be null, though for backward compatibility it's accepted when the locale to encoding Map (see earlier) is empty.
      • setSharedVariable

        public void setSharedVariable​(java.lang.String name,
                                      TemplateModel tm)
        Adds a shared variable to the configuration. Shared sharedVariables are sharedVariables that are visible as top-level sharedVariables for all templates which use this configuration, if the data model does not contain a variable with the same name.

        Never use TemplateModel implementation that is not thread-safe for shared sharedVariables, if the configuration is used by multiple threads! It is the typical situation for Servlet based Web sites.

        This method is not thread safe; use it with the same restrictions as those that modify setting values.

        Parameters:
        name - the name used to access the data object from your template. If a shared variable with this name already exists, it will replace that.
        See Also:
        setAllSharedVariables(freemarker.template.TemplateHashModelEx), setSharedVariable(String,Object)
      • getSharedVariableNames

        public java.util.Set getSharedVariableNames()
        Returns the set containing the names of all defined shared sharedVariables. The method returns a new Set object on each call that is completely disconnected from the Configuration. That is, modifying the set will have no effect on the Configuration object.
      • setAllSharedVariables

        public void setAllSharedVariables​(TemplateHashModelEx hash)
                                   throws TemplateModelException
        Adds all object in the hash as shared variable to the configuration; it's like doing several setSharedVariable(String, Object) calls, one for each hash entry. It doesn't remove the already added shared variable before doing this.

        Never use TemplateModel implementation that is not thread-safe for shared shared variable values, if the configuration is used by multiple threads! It is the typical situation for Servlet based Web sites.

        This method is not thread safe; use it with the same restrictions as those that modify setting values.

        Parameters:
        hash - a hash model whose objects will be copied to the configuration with same names as they are given in the hash. If a shared variable with these names already exist, it will be replaced with those from the map.
        Throws:
        TemplateModelException
        See Also:
        setSharedVaribles(Map), setSharedVariable(String,Object), setSharedVariable(String,TemplateModel)
      • clearSharedVariables

        public void clearSharedVariables()
        Removes all shared variables, except the predefined ones (compress, html_escape, etc.).
      • clearTemplateCache

        public void clearTemplateCache()
        Removes all entries from the template cache, thus forcing reloading of templates on subsequent getTemplate calls.

        This method is thread-safe and can be called while the engine processes templates.

      • removeTemplateFromCache

        public void removeTemplateFromCache​(java.lang.String name,
                                            java.util.Locale locale,
                                            java.lang.String encoding,
                                            boolean parse)
                                     throws java.io.IOException
        Throws:
        java.io.IOException
        Since:
        2.3.19
      • removeTemplateFromCache

        public void removeTemplateFromCache​(java.lang.String name,
                                            java.util.Locale locale,
                                            java.lang.Object customLookupCondition,
                                            java.lang.String encoding,
                                            boolean parse)
                                     throws java.io.IOException
        Removes a template from the template cache, hence forcing the re-loading of it when it's next time requested. This is to give the application finer control over cache updating than setTemplateUpdateDelay(int) alone does.

        For the meaning of the parameters, see getTemplate(String, Locale, Object, String, boolean, boolean).

        This method is thread-safe and can be called while the engine processes templates.

        Throws:
        java.io.IOException
        Since:
        2.3.28
      • getLocalizedLookup

        public boolean getLocalizedLookup()
        The getter pair of setLocalizedLookup(boolean).

        This method is thread-safe and can be called while the engine works.

      • setLocalizedLookup

        public void setLocalizedLookup​(boolean localizedLookup)
        Enables/disables localized template lookup. Enabled by default.

        With the default TemplateLookupStrategy, localized lookup works like this: Let's say your locale setting is Locale("en", "AU"), and you call cfg.getTemplate("foo.ftl"). Then FreeMarker will look for the template under these names, stopping at the first that exists: "foo_en_AU.ftl", "foo_en.ftl", "foo.ftl". See the description of the default value at setTemplateLookupStrategy(TemplateLookupStrategy) for a more details. If you need to generate different template names, use setTemplateLookupStrategy(TemplateLookupStrategy) with your custom TemplateLookupStrategy.

        Note that changing the value of this setting causes the template cache to be emptied so that old lookup results won't be reused (since 2.3.22).

        Historical note: Despite what the API documentation said earlier, this method is not thread-safe. While setting it can't cause any serious problems, and in fact it works well on most hardware, it's not guaranteed that FreeMarker will see the update in all threads.

      • getSettingNames

        public java.util.Set<java.lang.String> getSettingNames​(boolean camelCase)
        Returns the valid Configuration setting names. Naturally, this includes the Configurable setting names too.
        Overrides:
        getSettingNames in class Configurable
        Parameters:
        camelCase - If we want the setting names with camel case naming convention, or with snake case (legacy) naming convention.
        Since:
        2.3.24
        See Also:
        Configurable.getSettingNames(boolean)
      • getCorrectedNameForUnknownSetting

        protected java.lang.String getCorrectedNameForUnknownSetting​(java.lang.String name)
        Overrides:
        getCorrectedNameForUnknownSetting in class Configurable
        Parameters:
        name - The wrong name
        Returns:
        The corrected name, or null if there's no known correction
      • getVersionNumber

        @Deprecated
        public static java.lang.String getVersionNumber()
        Deprecated.
        Use getVersion() instead.
        Returns FreeMarker version number string.
      • getVersion

        public static Version getVersion()
        Returns FreeMarker version information, most importantly the major.minor.micro version numbers; do NOT use this as the value of the incompatible_improvements setting (as the parameter to Configuration(Version)), as then your application can break when you upgrade FreeMarker! Use a constant value, like VERSION_2_3_28, to protect your application from fixes/changes that aren't entirely backward compatible. Fixes and features that are backward compatible are always enabled. On FreeMarker version numbering rules:
        • For final/stable releases the version number is like major.minor.micro, like 2.3.19. (Historically, when micro was 0 the version strings was like major.minor instead of the proper major.minor.0, but that's not like that anymore.)
        • When only the micro version is increased, compatibility with previous versions with the same major.minor is kept. Thus freemarker.jar can be replaced in an existing application without breaking it.
        • For non-final/unstable versions (that almost nobody uses), the format is:
          • Starting from 2.3.20: major.minor.micro-extraInfo, like 2.3.20-nightly_20130506T123456Z, 2.4.0-RC01. The major.minor.micro always indicates the target we move towards, so 2.3.20-nightly or 2.3.20-M01 is after 2.3.19 and will eventually become to 2.3.20. "PRE", "M" and "RC" (uppercase!) means "preview", "milestone" and "release candidate" respectively, and is always followed by a 2 digit 0-padded counter, like M03 is the 3rd milestone release of a given major.minor.micro.
          • Before 2.3.20: The extraInfo wasn't preceded by a "-". Instead of "nightly" there was "mod", where the major.minor.micro part has indicated where are we coming from, so 2.3.19mod (read as: 2.3.19 modified) was after 2.3.19 but before 2.3.20. Also, "pre" and "rc" was lowercase, and was followd by a number without 0-padding.
        Since:
        2.3.20
      • getSupportedBuiltInNames

        public java.util.Set<java.lang.String> getSupportedBuiltInNames​(int namingConvention)
        Returns the names of the supported "built-ins". These are the (expr?builtin_name-like things). As of this writing, this information doesn't depend on the configuration options, so it could be a static method, but to be future-proof, it's an instance method.
        Parameters:
        namingConvention - One of AUTO_DETECT_NAMING_CONVENTION, LEGACY_NAMING_CONVENTION, and CAMEL_CASE_NAMING_CONVENTION. If it's AUTO_DETECT_NAMING_CONVENTION then the union of the names in all the naming conventions is returned.
        Since:
        2.3.24