Settings

设置 是影响 FreeMarker 行为的命名值。设置示例为:localenumber_formatdefault_encodingtemplate_exception_handler。完整的设置列表可在Configuration.setSetting(...)的 Java API 文档中找到。

来自Configuration的设置可以在Template实例中被覆盖。例如,如果在配置中将locale设置设置为"en_US",则在所有使用此配置的模板中locale都将是"en_US",但在locale被显式指定的模板中除外(请参见localization)。因此,Configuration中的设置值用作默认值,可以按每个模板方式覆盖它们。对于单个Template.process调用,可以进一步覆盖Configuration实例或Template实例的值。对于每个此类调用,都会在内部创建一个freemarker.core.Environment对象,该对象保存模板处理的运行时环境,包括在该级别上被覆盖的设置值。甚至可以在模板处理期间更改在那里存储的值,因此模板可以自行设置设置,例如在进行中的处理过程中切换locale

可以将其想象为 3 层设置(ConfigurationTemplateEnvironment),其中包含某个设置值的最顶层提供该设置的有效值。例如(设置 A 到 F 只是此示例的虚构设置):

Setting ASetting BSetting CSetting DSetting ESetting F
第 3 层:Environment1--1--
第 2 层:Template22--2-
第 1 层:Configuration3333--

设置的有效值为:A = 1,B = 2,C = 3,D = 1,E =2.F 设置可能是null,否则在尝试获取它时会引发异常。

让我们确切地了解如何设置设置:

  • Configuration层:原则上,您可以使用Configuration对象的 setter 方法来设置设置,例如:
Configuration myCfg = new Configuration(Configuration.VERSION_2_3_27);
myCfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
myCfg.setDefaultEncoding("UTF-8");
DefaultObjectWrapperBuilder owb = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_27);
owb.setForceLegacyNonListCollections(false);
owb.setDefaultDateType(TemplateDateModel.DATETIME);
myCfg.setObjectWrapper(owb.build());

您必须先开始使用Configuration对象(通常是在初始化应用程序时),然后才能执行此操作。之后,您应该将该对象视为只读。

实际上,在大多数框架中,您必须在某种特定于框架的配置文件中指定设置,这些文件要求将设置指定为String个名称/值对(例如在.properties文件中)。在那种情况下,框架的作者最有可能使用Confguration.setSetting(String name, String value)方法。请参阅setSetting 的 API 文档中可用的设置名称和值的格式。 Spring 框架示例:

<bean id="freemarkerConfig"
    class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
  <property name="freemarkerSettings">
    <props>
      <prop key="incompatible_improvements">2.3.27</prop>
      <prop key="template_exception_handler">rethrow</prop>
      <prop key="default_encoding">UTF-8</prop>
      <prop key="object_wrapper">
        DefaultObjectWrapper(
                2.3.27,
                forceLegacyNonListCollections = false,
                defaultDateType = freemarker.template.TemplateDateModel.DATETIME)
      </prop>
    </props>
  </property>
</bean>

在为 Struts 配置 FreeMarker 时,这是相同的,它在 Classpath 中查找freemarker.properties

incompatible_improvements=2.3.27
template_exception_handler=rethrow
default_encoding=UTF-8
object_wrapper=DefaultObjectWrapper( \
        2.3.27, \
        forceLegacyNonListCollections = false, \
        defaultDateType = freemarker.template.TemplateDateModel.DATETIME)

如上面的object_wrapper所示,某些设置可以接受非常复杂的值,这些值可以用于实例化任意类的对象并设置其属性。尽管如此,与直接使用 Java API 相比,使用String键-值对进行配置仍然受到限制,因此在某些情况下,您必须找到一种使用 Java 进行此操作的方法。

  • Template层:单个模板上的设置通常由模板配置(请参阅各自的章节)设置,该设置基本上将设置分配与模板名称(模板路径)模式相关联。 locale设置与这种方法存在偏差,因为您还可以指定Configuration.getTemplate(...)作为参数,以获取请求的语言环境的模板(所谓的本地化查找)。

Warning!

您永远不要直接在从Configuration.getTemplate(...)获取的Template对象上设置设置!这些对象应被视为已初始化且为只读。

当模板包含或导入另一个模板时,大多数设置(如localenumber_format等)将保留顶级模板指定的设置。exceptions 是影响模板解析的设置(例如tag_syntaxwhitespace_stripping等),因为这些设置不是从顶级模板继承的,而是每个模板始终使用其自己的值,而不管其调用方式。

Note:

如果要使用模板层设置,则应将incompatible_improvements 设置设置为 2.3.22 或更高版本,以避免造成一些令人困惑的旧版错误。

  • Environment层:有两种方法:

  • 使用 Java API:使用Environment对象的 setter 方法。您可能会遇到myTemplate.process(...)都在内部创建Environment对象并处理模板的 API 问题,因此您没有机会在两者之间调整Environment。解决方案是可以将这两个步骤分开,如下所示:

Environment env = myTemplate.createProcessingEnvironment(root, out);
env.setLocale(java.util.Locale.ITALY);
env.setNumberFormat("0.####");
env.process();  // process the template
  • 直接在模板中(通常被认为是不良样式):使用setting directive,例如:
<#setting locale="it_IT">
<#setting number_format="0.####">

关于何时可以更改此层中的设置没有任何限制。

要查看支持的设置及其含义的列表,请阅读 FreeMarker Java API 文档的以下部分:

  • 所有三层中的设置的freemarker.core.Configurable的设置方法

  • 设置freemarker.template.Configuration的设置方法,这些设置仅在Configuration层中可用

  • freemarker.core.Configurable.setSetting(String, String)表示在所有三个层中都可用并且可以与String键值对一起写入的设置。

  • freemarker.template.Configuration.setSetting(String, String)用于仅在Configuration层中可用并且可以与String键/值对一起写入的设置。