Settings are named values that
influence the behavior of FreeMarker. Examples of settings are:
locale
, number_format
,
default_encoding
,
template_exception_handler
. The full list of
settings can be found in the Java
API documentation of
Configuration.setSetting(...)
.
Settings stored in Configuration
instance can
be overridden in a Template
instance. For example
you set "en_US"
for the locale
setting in the configuration, then the locale
in
all templates that use this configuration will be
"en_US"
, except in templates where the locale was
explicitly specified differently (see localization). Thus,
values in a Configuration
serve as defaults that
can be overridden in a per template manner. The value comes from
Configuration
instance or
Template
instance can be further overridden for a
single Template.process
call. For each such call a
freemarker.core.Environment
object is created
internally that holds the runtime environment of the template
processing, including the setting values that were overridden on that
level. The values stored there can even be changed during the template
processing, so a template can set settings itself, like switching
locale
at the middle of the output.
This can be imagined as 3 layers
(Configuration
, Template
,
Environment
) of settings, where the topmost layer
that contains the value for a certain setting provides the effective
value of that setting. For example (settings A to F are just imaginary
settings for this example):
Setting A | Setting B | Setting C | Setting D | Setting E | Setting F | |
---|---|---|---|---|---|---|
Layer 3: Environment |
1 | - | - | 1 | - | - |
Layer 2: Template |
2 | 2 | - | - | 2 | - |
Layer 1: Configuration |
3 | 3 | 3 | 3 | - | - |
The effective value of settings will be: A = 1, B = 2, C = 3, D
= 1, E = 2. The F setting is probably null
, or it
throws exception when you try to get it.
Let's see exactly how to set settings:
-
Configuration
layer: In principle you set the settings with the setter methods of theConfiguration
object, fore example:Configuration myCfg = new Configuration(Configuration.VERSION_2_3_23); myCfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); myCfg.setDefaultEncoding("UTF-8");
You do it before you start to actually use the
Configuration
object (typically, when you initialize the application); you should treat the object as read-only after that.In practice, in most Web application frameworks you have to specify the settings in a framework-specific configuration file that require specifying setting as
String
name-value pairs (like in a.properties
file). In that case the authors of the frameworks most probably use thesetSetting(String name, String value)
method ofConfiguration
; see available setting names and the format of the values in the API doc ofsetSetting
. Example for Spring Framework:<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <property name="freemarkerSettings"> <props> <prop key="incompatible_improvements">2.3.23</prop> <prop key="template_exception_handler">rethrow</prop> <prop key="default_encoding">UTF-8</prop> </props> </property> </bean>
Note that this kind of configuring (
String
key-value pairs) is unfortunately limited compared to directly using the API ofConfiguration
. -
Template
layer: Thelocale
setting of the template is set byConfiguration.getTemplate(...)
to the requested locale. Otherwise you shouldn't set settings here, unless you manage theTemplate
objects instead of afreemarker.cache.TemplateCache
, in which case you should set the setting before theTemplate
object is first used, and then treat theTemplate
object as read-only. -
Environment
layer: There are two ways doing it:-
With Java API: Use the setter methods of the
Environment
object. Certainly you want to do that just before the processing of the template is started, and then you run into the problem that when you callmyTemplate.process(...)
it creates theEnvironment
object internally and the immediately processes the template, so you had no chance. The solution is that this two steps can be separated like this:Environment env = myTemplate.createProcessingEnvironment(root, out); env.setLocale(java.util.Locale.ITALY); env.setNumberFormat("0.####"); env.process(); // process the template
-
Directly in the Template (considered as bad style, usually): Use the
setting
directive, for example:<#setting locale="it_IT"> <#setting number_format="0.####">
There are no restriction regarding when can you change the settings in this layer.
-
To see the list of supported settings and their meaning, please read the following parts of the FreeMarker Java API documentation:
-
Setter methods of
freemarker.core.Configurable
for the settings that are in all three layers -
Setter methods of
freemarker.template.Configuration
for the settings that are available only in theConfiguration
layer -
freemarker.core.Configurable.setSetting(String, String)
for settings that are available in all three layers and are writable withString
key-value pairs. -
freemarker.template.Configuration.setSetting(String, String)
for settings that are available only in theConfiguration
layer and are writable withString
key-value pairs.