2010-04-13 29 views
6

我们正在尝试在freemarker中构建一个系统,其中可以选择添加扩展文件来替换标准模板的块。在freemarker中,有可能在包含文件之前检查文件是否存在?

我们得到了这一点

<#attempt> 
    <#include "extension.ftl"> 
<#recover> 
    Standard output 
</#attempt> 

所以 - 如果extension.ftl文件存在,将被使用,否则恢复块的部分内输出。

问题在于,freemarker总是记录导致恢复块触发的错误。

因此,我们需要一两件事情:

  1. 别叫包括:如果文件不存在 - 这样就需要检查文件的存在。

-OR-

  • 以防止错误的恢复块内的记录,而不改变日志,以防止从显示出来的freemarker ALL误差的方式。
  • +0

    这并不直接回答你的问题,但你有没有考虑使用自定义的'TemplateLoader'呢?例如http://freemarker.org/docs/api/freemarker/template/Configuration.html#setTemplateLoader%28freemarker.cache.TemplateLoader%29 – ZoogieZork 2010-04-13 22:31:41

    +0

    被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

    +0

    祝我可以关闭这个问题 - 我不能接受任何答案,因为我不在这个项目了,所以我不知道他们是否工作。对于那个很抱歉。 – harmanjd 2013-01-22 18:30:00

    回答

    -1

    尝试使用此方法获得的基本路径:

    <#assign objectConstructor = "freemarker.template.utility.ObjectConstructor"?new()> 
    <#assign file = objectConstructor("java.io.File","")> 
    <#assign path = file.getAbsolutePath()> 
    <script type="text/javascript"> 
    alert("${path?string}"); 
    </script> 
    

    那么这个走的目录结构:

    <#assign objectConstructor = "freemarker.template.utility.ObjectConstructor"?new()> 
    <#assign file = objectConstructor("java.io.File","target/test.ftl")> 
    <#assign exist = file.exists()> 
    <script type="text/javascript"> 
    alert("${exist?string}"); 
    </script> 
    
    +0

    此解决方案无法解析文件路径,总是落在else分支中 – Raul 2013-05-24 16:13:00

    0

    我有这个确切的需要以及,但我不想使用FreeMarker的ObjectConstructor(它感觉太像我的口味scriptlet)。

    我写了一个定制FileTemplateLoader

    public class CustomFileTemplateLoader 
        extends FileTemplateLoader { 
    
        private static final String STUB_FTL = "/tools/empty.ftl"; 
    
        public CustomFileTemplateLoader(File baseDir) throws IOException { 
         super(baseDir); 
        } 
    
    
        @Override 
        public Object findTemplateSource(String name) throws IOException { 
         Object result = null; 
         if (name.startsWith("optional:")) { 
          result = super.findTemplateSource(name.replace("optional:", "")); 
          if (result == null) { 
           result = super.findTemplateSource(STUB_FTL); 
          } 
         } 
    
         if (result == null) { 
          result = super.findTemplateSource(name); 
         } 
    
         return result; 
        } 
    
    } 
    

    而我相应的FreeMarker宏:

    <#macro optional_include name> 
        <#include "/optional:" + name> 
    </#macro> 
    

    空FTL文件要求(/tools/empty.ftl)刚刚包含注释解释它的存在。

    结果是,如果找不到请求的FTL,则“可选”包含将仅包含此空FTL。

    2

    更容易的解决办法是:

    <#attempt> 
        <#import xyz.ftl> 
        your_code_here 
    <#recover> 
    </#attempt> 
    
    +0

    我试过了,没有用。 – 3urdoch 2013-06-13 17:20:48

    0

    我们写这解决了这个对我们是一个自定义宏。在早期测试中,它运行良好。要包含它,添加如下内容(其中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()); 
          } 
         } 
        } 
    } 
    
    0

    您可以使用也可以使用Java的方法来检查文件存在与否。

    的Java方法 -

    public static boolean checkFileExistance(String filePath){ 
          File tmpDir = new File(filePath); 
         boolean exists = tmpDir.exists(); 
         return exists; 
        } 
    

    Freemarker的代码 -

    <#assign fileExists = (Static["ClassName"].checkFileExistance("Filename"))?c/> 
    <#if fileExists = "true"> 
        <#include "/home/demo.ftl"/> 
        <#else> 
         <#include "/home/index.ftl"> 
    </#if> 
    
    相关问题