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

includeに 'parse = true'オプションを使用できますか? '<#include" inc/headerのようなものです。ftl "parse = true>' – varren

+0

フラグメント化されていない 'fragment.design'文字列内のFreemarker変数です – crm

答えて

1

代わりにきれいになります。

// 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; 
    } 
} 

設定でそれを登録し、テンプレートは次のようになります。

関連資料:

なお、あなたは多くのことを実行する必要がある場合?interpret -s /秒であり、同じものを解釈する傾向があります文字列を何度も繰り返し使用すると、これらの文字列で作られたTemplate -sをキャッシュして再利用するカスタムソリューションが必要になることがあります。しかし、ほとんどのアプリケーションでは、?interpretではパフォーマンスに問題はありません。

!に注意してください)を使用している場合は、#if fragments??は必要ありません。

+0

はるかにクリーンなソリューションです。 – crm

1

オプション1:javaコントローラで文字列を処理します。

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

オプション2:この方法は、あなたはテンプレート

@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(); 
} 

テンプレート一部を変更する必要はありませんあなたはテンプレートで使用できるカスタムmethod expressionを作成します。 01を使用し、

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

しかし、コントローラは${fragment.design?html}

@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

関連する問題