2017-10-21 117 views
1

我从包含HTML和Freemarker语法混合的数据库中检索字符串值。如何使用Freemarker变量分析字符串HTML

像这样:

<p>${fragment.title}</p> 
<table id='resultsTable' class='material-table'> 
    <tr> 
     <th>Instruction</th> 
     <th>Action</th> 
    </tr> 
Test 
</table> 

以下是我如何访问上面的字符串在Freemarker模板:

<#include "inc/header.ftl"> 
<body> 
<#include "inc/navigation.ftl"> 
<div class="container"> 
    <div class="row"> 
     <#if fragments??> 
      <#list fragments as fragment> 
       <div class="col-sm-6"> 
        <div class="fragment"> 
         ${fragment.design?html} 
        </div> 
       </div>    
      </#list> 
     </#if> 
    </div> 
</div> 
</body> 
<#include "inc/footer.ftl"> 

但产量并不完全正确:

<p>${fragment.title}</p> <table id='resultsTable' class='material-table'> <tr> struction</th> </th> </tr> ddd </table> 

如何使用Freemarker解析HTML并同时解析${fragment.title}的值?

+0

你可以尝试使用'parse = true'选项来包含吗?比如'<#include“inc/header。ftp“parse = true>' – varren

+0

这是'fragment.design'字符串中的Freemarker变量,它们没有被解析。 – crm

回答

1

相反的${fragment.design?html},使用<@fragment.design?interpret />

相关文档:

请注意,如果你需要运行很多每秒?interpret-s,你倾向于解释相同字符串一次又一次地在您的模板中,您可能需要一些自定义解决方案来缓存和重用从这些字符串中生成的Template。但是,在大多数应用程序中,性能不是?interpret的问题。

顺便说一句,如果你使用<#list fragments! as fragment>(注意!),你不需要那个#if fragments??

+0

迄今为止最干净的解决方案。 – crm

1

选项一:在java控制器中处理您的字符串。这样,您就不需要更改模板

@RequestMapping("/test2") 
public ModelAndView test2() throws IOException, TemplateException { 
    Map<String, String> fragment = new HashMap<>(); 
    fragment.put("title", "Some Title"); 
    ModelAndView model = new ModelAndView("index", "fragment", fragment); 

    //your string should go here instead of this default 
    String template = "<div>${fragment.title}</div> <div>some other test</div>"; 
    fragment.put("design", processTemplate(model.getModel(), template)); 

    return model; 
} 

private String processTemplate(Map model, String template) 
     throws IOException, TemplateException { 
    Template t = new Template("TemplateFromDBName", template, 
      Environment.getCurrentEnvironment().getConfiguration()); 
    Writer out = new StringWriter(); 
    t.process(model, out); 
    return out.toString(); 
} 

模板部分:

<div class="fragment"> 
    ${fragment.design} 
</div> 

选择二:创建自定义method expression,你可以在模板中使用。

// http://freemarker.org/docs/pgui_datamodel_method.html 
public static class ProcessString implements TemplateMethodModelEx { 

    public static final String PROCESS_STRING_FUNCTION_NAME = "processString"; 

    public TemplateModel exec(List args) throws TemplateModelException { 
     if (args.size() != 1) throw new TemplateModelException("Wrong arguments"); 

     try { 
      Environment env = Environment.getCurrentEnvironment(); 
      Template t = new Template("TemplateFromDBName", 
        args.get(0).toString(), env.getConfiguration()); 

      Writer out = new StringWriter(); 
      t.process(env.getDataModel(), out); 
      return new SimpleScalar(out.toString()); 
     } catch (IOException | TemplateException e) { 
      e.printStackTrace(); 
     } 

     return new SimpleScalar(""); 

    } 
} 

配置寄存器它

@Configuration 
public class FreeMarkerConfig extends WebMvcConfigurerAdapter { 
    @Bean 
    @Primary 
    public FreeMarkerConfigurer freemarkerConfig() { 
     FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer(); 
     // some other config here 

     Map properties = new HashMap(); 
     properties.put(ProcessString.PROCESS_STRING_FUNCTION_NAME, 
       new ProcessString()); 

     freeMarkerConfigurer.setFreemarkerVariables(properties); 
     return freeMarkerConfigurer; 
    } 
} 

而且模板的样子:

<div class="fragment"> 
    ${processString(fragment.design)} 
</div> 

但是控制器会干净

@RequestMapping("/test") 
public ModelAndView test() throws IOException, TemplateException { 
    Map<String, String> fragment = new HashMap<>(); 
    fragment.put("title", "Some Title"); 
    fragment.put("design", "<div>${fragment.title}</div><div> other test</div>"); 
    return new ModelAndView("index", "fragment", fragment); 
} 
+0

谢谢。这两个解决方案都可以工作。 – crm