【发布时间】:2010-11-15 13:05:30
【问题描述】:
我已经使用FreeMarker 有一段时间了,但是有一个明显的功能缺失或者我无法弄清楚(我希望是后者!)。如果你通过 cfg.getTemplate() 一个绝对路径,它就不起作用。我知道你可以指定一个模板目录,但我不能这样做,我的用例可以处理任何目录中的文件。有什么方法可以设置 FreeMarker 以任何用户期望的方式呈现绝对路径?
【问题讨论】:
标签: java linux freemarker
我已经使用FreeMarker 有一段时间了,但是有一个明显的功能缺失或者我无法弄清楚(我希望是后者!)。如果你通过 cfg.getTemplate() 一个绝对路径,它就不起作用。我知道你可以指定一个模板目录,但我不能这样做,我的用例可以处理任何目录中的文件。有什么方法可以设置 FreeMarker 以任何用户期望的方式呈现绝对路径?
【问题讨论】:
标签: java linux freemarker
Freemarker 默认使用 FileTemplateLoader,它不允许您从“基本”目录之外获取模板(默认情况下取自“user.dir”系统属性,因此它是您的主目录)。你可以做的是:
【讨论】:
我必须使用绝对路径,因为模板是在 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());
// ...
}
【讨论】:
实际上它删除了开头的“/”所以你需要重新添加它
public Object findTemplateSource(String name) throws IOException {
File source = new File("/" + name);
return source.isFile() ? source : null;
}
【讨论】:
接受的解决方案的问题是,路径名在使用 TemplateLoader 之前在 FreeMarker 中被破坏。请参阅模板缓存:
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());
【讨论】: