【问题标题】:How to parse String HTML with Freemarker variables如何使用 Freemarker 变量解析字符串 HTML
【发布时间】:2018-04-02 18:50:43
【问题描述】:

我正在从包含 HTML 和 Freemarker 语法混合的数据库中检索一个字符串值。

像这样:

<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}的值?

【问题讨论】:

  • 您可以尝试使用parse=true 选项来包含吗?喜欢&lt;#include "inc/header.ftl" parse=true&gt;
  • fragment.design 字符串中的 Freemarker 变量未被解析。

标签: java html spring spring-boot freemarker


【解决方案1】:

使用&lt;@fragment.design?interpret /&gt;,而不是${fragment.design?html}

相关文档:

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

顺便说一句,如果您使用&lt;#list fragments! as fragment&gt;,则不需要#if fragments??(请注意!)。

【讨论】:

    【解决方案2】:

    选项一:在 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-16
      • 2023-03-08
      • 2015-02-06
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多