简体   繁体   English

在Freemarker模板中加载模板,而无需设置模板的目录或类

[英]Loading templates in Freemarker templates without setting Directory or Class for template loading

Is there any way of loading the Freemarker templates directly without having need to first load the Directory from which templates will be loaded or setting the Class relative to which templates will be loaded. 有什么方法可以直接加载Freemarker模板,而无需先加载要从中加载模板的Directory或设置相对于要加载模板的Class

ie Is there any way so that i can load a template like 即有什么办法让我可以像这样加载模板

Template template = getTemplate("PathToTemplate/myTemplate.ftl");

I need this, because user specifies the complete path to ftl files. 我需ftl ,因为用户指定了ftl文件的完整路径。 So,first i have to separate directory name and file name, then i am doing 所以,首先我必须分开目录名和文件名,然后我在做

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);

I do not want to do all this. 我不想做所有这一切。

The getTemplate method is heavily overloaded. getTemplate方法非常重载。 As per the documentation the method getTemplate(String, Locale, String, boolean) will eventually be called regardless which getTemplate method you called. 根据文档,无论调用哪个getTemplate方法,最终都会调用方法getTemplate(String, Locale, String, boolean)

This method's documentation expresses the following: 该方法的文档表示以下内容:

The exact syntax of the name is interpreted by the underlying TemplateLoader, but the cache makes some assumptions. 名称的确切语法由基础TemplateLoader解释,但是缓存进行了一些假设。 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". 它总是相对于“模板根目录”进行解释。

There are two notable things: 有两个值得注意的事情:

  1. The name parameter is already handling a hierarchical path, but must not begin with a slash. name参数已经在处理层次结构路径,但不能以斜杠开头。 So maybe you could set the configuration's directory once to the root of your disk and then simply provide the full path (but without the leading slash). 因此,也许您可​​以将配置的目录设置一次到磁盘的根目录,然后简单地提供完整路径(但不带斜杠)。

  2. The documentation explains something about a TemplateLoader . 该文档说明了有关TemplateLoader So you can simply write an implementation of that interface for loading the template. 因此,您可以简单地编写该接口的实现以加载模板。 In that implementation you have full hands on the provided name . 在该实现中,您可以完全使用提供的名称

Templates can be created by directly calling a Template constructor, to which you pass a String or Reader as argument. 可以通过直接调用Template构造函数来创建Template ,将StringReader作为参数传递给它。 Then of course you get that Reader or String from wherever you want. 然后,当然可以从任何地方获取该ReaderString This approach has two disadvantages though: 但是,此方法有两个缺点:

  • Other templates won't be able to #import or #include those templates, as FreeMarker doesn't know how to load them (only you do) 其他模板将无法#import#include这些模板,因为FreeMarker不知道如何加载它们(只有您可以这样做)

  • Caching those templates (if that's needed anyway) is up to you 缓存那些模板(如果仍然需要)取决于您

If the above two is a problem for you, then see Seelenvirtuose's answer: create a TemplateLoader that interprets the template names as full paths. 如果以上两个对您来说都是问题,请参阅Seelenvirtuose的答案:创建一个TemplateLoader ,将模板名称解释为完整路径。

As of your example code, know that the Configuration instance will clear its template cache every time you replace the TemplateLoader . 在示例代码中,请知道,每次替换TemplateLoader时, Configuration实例都会清除其模板缓存。 Also note that it's not thread-safe to do. 还要注意,这样做不是线程安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM