在 Freemarker 模板中加载模板而不为模板加载设置目录或类
Posted
技术标签:
【中文标题】在 Freemarker 模板中加载模板而不为模板加载设置目录或类【英文标题】:Loading templates in Freemarker templates without setting Directory or Class for template loading 【发布时间】:2014-09-15 15:00:45 【问题描述】:有没有什么方法可以直接加载 Freemarker 模板,而无需首先加载要从中加载模板的 Directory
或设置相对于要加载的模板的 Class
。
即有什么方法可以让我加载模板,如
Template template = getTemplate("PathToTemplate/myTemplate.ftl");
我需要这个,因为用户指定了ftl
文件的完整路径。所以,首先我必须将目录名和文件名分开,然后我正在做
Configuration cfg = new Configuration();
int indexOfLast = templatePath.lastIndexOf("\\");
String dir = templatePath;
String fileName="";
if(indexOfLast>=0)
dir = templatePath.substring(0,indexOfLast);
fileName= templatePath.substring(indexOfLast+1,templatePath.length());
cfg.setDirectoryForTemplateLoading(new File(dir));
Template template = cfg.getTemplate(fileName);
我不想做这一切。
【问题讨论】:
loading the Freemarker templates directly
是什么意思 - 你的 PathToTemplate
应该在哪里?它与某物有关吗?还是绝对的?
@KonstantinV.Salikhov 它在连接的网络上。 Loading templates directly
表示我不想要两个步骤。首先设置加载模板的目录或路径,然后config.getTemplate('templateFile.ftl')
获取模板。而是something.getTemplate('dir path/templateFile.ftl')
【参考方案1】:
可以通过直接调用Template
构造函数来创建模板,并将String
或Reader
作为参数传递给该构造函数。然后当然你可以从任何你想要的地方得到Reader
或String
。这种方法有两个缺点:
其他模板将无法 #import
或 #include
这些模板,因为 FreeMarker 不知道如何加载它们(只有你会这样做)
缓存这些模板(如果需要的话)由您决定
如果以上两个对您来说是个问题,那么请参阅 Seelenvirtuose 的回答:创建一个 TemplateLoader
,将模板名称解释为完整路径。
在您的示例代码中,知道Configuration
实例将在您每次替换TemplateLoader
时清除其模板缓存。另请注意,这不是线程安全的。
【讨论】:
【参考方案2】:getTemplate
方法严重过载。根据文档,无论您调用了哪个 getTemplate
方法,最终都会调用方法 getTemplate(String, Locale, String, boolean)
。
该方法的文档表述如下:
名称的确切语法由底层 TemplateLoader 解释,但缓存做了一些假设。首先,名称应该是一个分层路径,路径组件由斜杠字符分隔(不是反斜杠!)。此处给出的路径(名称)不能以斜杠开头;它总是相对于“模板根目录”进行解释。
有两点值得注意:
name
参数已经在处理分层路径,但不能以斜杠开头。因此,也许您可以将配置的目录 once 设置为磁盘的根目录,然后简单地提供完整路径(但没有前导斜杠)。
文档解释了一些关于 TemplateLoader
的内容。因此,您可以简单地编写该接口的实现来加载模板。在该实现中,您可以完全掌握提供的 name。
【讨论】:
以上是关于在 Freemarker 模板中加载模板而不为模板加载设置目录或类的主要内容,如果未能解决你的问题,请参考以下文章
Freemarker 在 maven 生成的 jar 中加载模板的位置