我一直在使用FreeMarker一段时间,但有一个明显的功能要么丢失要么我想不出来(我希望后者!)。如果你传递cfg.getTemplate()一个绝对路径,它就行不通。我知道你可以指定一个模板目录,但我负担不起,我的用例可以处理任何目录中的文件。有没有办法设置FreeMarker以任何用户期望的方式呈现绝对路径?
答案 0 :(得分:6)
我必须使用绝对路径,因为模板在Ant脚本中发生,模板在文件系统上并使用Ant文件集发现。我想这些都是一些独特的要求......
无论如何,对于后代(只要SO上去),这是一个有效的解决方案:
public class TemplateAbsolutePathLoader implements TemplateLoader {
public Object findTemplateSource(String name) throws IOException {
File source = new File(name);
return source.isFile() ? source : null;
}
public long getLastModified(Object templateSource) {
return ((File) templateSource).lastModified();
}
public Reader getReader(Object templateSource, String encoding)
throws IOException {
if (!(templateSource instanceof File)) {
throw new IllegalArgumentException("templateSource is a: " + templateSource.getClass().getName());
}
return new InputStreamReader(new FileInputStream((File) templateSource), encoding);
}
public void closeTemplateSource(Object templateSource) throws IOException {
// Do nothing.
}
}
,初始化为:
public String generate(File template) {
Configuration cfg = new Configuration();
cfg.setTemplateLoader(new TemplateAbsolutePathLoader());
Template tpl = cfg.getTemplate(template.getAbsolutePath());
// ...
}
答案 1 :(得分:2)
实际上它会删除开头“/”,因此您需要将其添加回
public Object findTemplateSource(String name) throws IOException {
File source = new File("/" + name);
return source.isFile() ? source : null;
}
答案 2 :(得分:1)
Freemarker默认使用FileTemplateLoader,它不允许你从“base”目录之外获取模板(默认情况下,它来自'user.dir'系统属性,因此它是你的主目录)。你能做的是:
答案 3 :(得分:0)
接受的解决方案的问题是,在使用TemplateLoader之前,路径名在FreeMarker中被销毁。请参见TemplateCache:
name = normalizeName(name);
if(name == null) {
return null;
}
Template result = null;
if (templateLoader != null) {
result = getTemplate(templateLoader, name, locale, encoding, parseAsFTL);
}
所以我认为最好使用建议的解决方案in this answer
例如
Configuration config = new Configuration();
File templateFile = new File(templateFilename);
File templateDir = templateFile.getParentFile();
if ( null == templateDir ){
templateDir = new File("./");
}
config.setDirectoryForTemplateLoading(templateDir);
Template template = config.getTemplate(templateFile.getName());