2017-10-21 87 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