Freemarker 模板加载

Posted

技术标签:

【中文标题】Freemarker 模板加载【英文标题】:Freemarker template loading 【发布时间】:2013-03-18 14:51:46 【问题描述】:

在我的应用程序中,所有 freemarker 模板都在 /templates/ftl/ 中,因此在应用程序部署期间,我加载了一个类,我调用了一个扩展 FreemarkerManager 并具有方法的类

Configuration configuration = super.createConfiguration(servletContext);
configuration.setDirectoryForTemplateLoading(new File("/templates/ftl/"));

这样,当我需要加载一个模板文件时,我可以简单地这样做:

    ServletContext servletContext = ServletActionContext.getServletContext();
    Configuration configFreemarker = (Configuration) servletContext
                    .getAttribute("freemarker.Configuration");
    Template template = configFreemarker.getTemplate("pathToMyTemplate");

仅在一种特定情况下,我需要获取一个来自完全不同路径(而不是 /templates/ftl/)的模板。

如何在这个特定时刻声明用于模板加载的第二个目录而不破坏所有调用旧路径的现有代码?我可以同时有 2 个不同的模板加载起点吗?

谢谢

【问题讨论】:

也许只是创建没有特定目录的单独(或临时)配置? 我看不到如何实例化 2 个配置,因为我的类需要扩展 FreemarkerManager 并且我需要扩展我已经第一次做的方法 createConfiguration。在里面我得到配置 conf = super.createConfiguration(servletContext);但我看不到如何获得相同 servletContext 的第二个配置 【参考方案1】:

您可以使用MultipleTemplateLoader

import freemarker.cache.*; // template loaders live in this package

...

FileTemplateLoader ftl1 = new FileTemplateLoader(new File("/tmp/templates"));
FileTemplateLoader ftl2 = new FileTemplateLoader(new File("/usr/data/templates"));
ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), "");
TemplateLoader[] loaders = new TemplateLoader[]  ftl1, ftl2, ctl ;
MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);

cfg.setTemplateLoader(mtl);

来源:Freemarker Manual

【讨论】:

【参考方案2】:

另一种更优雅的方式(在我看来)是在配置 xml 中:

<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
  <property name="templateLoaderPaths">
        <value>/path1/ , /path2/</value>
  </property>
</bean>

【讨论】:

以上是关于Freemarker 模板加载的主要内容,如果未能解决你的问题,请参考以下文章

从数据库加载 FreeMarker 模板

在 Freemarker 模板中加载模板而不为模板加载设置目录或类

freemarker模板加载TemplateLoader常见方式

Java基础之Freemarker模板加载及清空机制

FreeMarker 模板加载器返回 302 Found

Spring Boot + Apache Camel + Freemarker 自定义模板加载器