我们写这解决了这个对我们是一个自定义宏。在早期测试中,它运行良好。要包含它,添加如下内容(其中MM是一个Spring ModelMap):
mm.addAttribute(IncludeIfExistsMacro.MACRO_NAME, new IncludeIfExistsMacro());
import java.io.IOException;
import java.util.Map;
import org.apache.commons.io.FilenameUtils;
import freemarker.cache.TemplateCache;
import freemarker.cache.TemplateLoader;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
/**
* This macro optionally includes the template given by path. If the template isn't found, it doesn't
* throw an exception; instead it renders the nested content (if any).
*
* For example:
* <@include_if_exists path="module/${behavior}.ftl">
* <#include "default.ftl">
* </@include_if_exists>
*
* @param path the path of the template to be included if it exists
* @param nested (optional) body could be include directive or any other block of code
*/
public class IncludeIfExistsMacro implements TemplateDirectiveModel {
private static final String PATH_PARAM = "path";
public static final String MACRO_NAME = "include_if_exists";
@Override
public void execute(Environment environment, Map map, TemplateModel[] templateModel,
TemplateDirectiveBody directiveBody) throws TemplateException, IOException {
if (! map.containsKey(PATH_PARAM)) {
throw new RuntimeException("missing required parameter '" + PATH_PARAM + "' for macro " + MACRO_NAME);
}
// get the current template's parent directory to use when searching for relative paths
final String currentTemplateName = environment.getTemplate().getName();
final String currentTemplateDir = FilenameUtils.getPath(currentTemplateName);
// look up the path relative to the current working directory (this also works for absolute paths)
final String path = map.get(PATH_PARAM).toString();
final String fullTemplatePath = TemplateCache.getFullTemplatePath(environment, currentTemplateDir, path);
TemplateLoader templateLoader = environment.getConfiguration().getTemplateLoader();
if (templateLoader.findTemplateSource(fullTemplatePath) != null) {
// include the template for the path, if it's found
environment.include(environment.getTemplateForInclusion(fullTemplatePath, null, true));
} else {
// otherwise render the nested content, if there is any
if (directiveBody != null) {
directiveBody.render(environment.getOut());
}
}
}
}
这并不直接回答你的问题,但你有没有考虑使用自定义的'TemplateLoader'呢?例如http://freemarker.org/docs/api/freemarker/template/Configuration.html#setTemplateLoader%28freemarker.cache.TemplateLoader%29 – ZoogieZork 2010-04-13 22:31:41
被FreeMarker的[用户自定义指令]解决[1] 你可以试试。 [1]:http://stackoverflow.com/questions/13908848/how-to-check-the-existense-of-a-freemarker-template-before-include-it/13908987#13908987 – jackalope 2012-12-17 08:18:54
祝我可以关闭这个问题 - 我不能接受任何答案,因为我不在这个项目了,所以我不知道他们是否工作。对于那个很抱歉。 – harmanjd 2013-01-22 18:30:00