【问题标题】:Dynamic template resolver using Thymeleaf使用 Thymeleaf 的动态模板解析器
【发布时间】:2021-01-28 01:22:19
【问题描述】:

我们需要动态解析 html 或文本模板。具有可变占位符的模板内容(字符串)将在数据库中可用。

我们必须根据需要使用变量的实际值动态解析它们并获得最终的字符串内容。

示例:(不是完整的代码)

String myHtmlTemplateContent = "<h1>Hi ${first_name} ${last_name}</h1>";
Map<String, Object> myMapWithValues = ..;
engine.resolve(myHtmlTemplateContent , myMapWithValues );

如果我们有办法使用 thymeleaf 解决问题或者是否可以使用 thymeleaf 模板引擎,将会很有帮助。

【问题讨论】:

    标签: java spring spring-boot thymeleaf template-engine


    【解决方案1】:

    我使用了以下方法:

    import org.thymeleaf.TemplateEngine;
    import org.thymeleaf.templatemode.TemplateMode;
    import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
    import org.thymeleaf.context.Context;
    import java.util.Map;
    
    public class GenericTemplateEngine {
    
        private final TemplateEngine templateEngine;
    
        public GenericTemplateEngine(TemplateMode templateMode) {
    
            templateEngine = new org.thymeleaf.TemplateEngine();
    
            ClassLoaderTemplateResolver templateResolver
                    = new ClassLoaderTemplateResolver(Thread
                            .currentThread().getContextClassLoader());
            templateResolver.setTemplateMode(templateMode);
            templateResolver.setPrefix("/thymeleaf/");
            templateResolver.setCacheTTLMs(3600000L); // one hour
            templateResolver.setCacheable(true);
            this.templateEngine.setTemplateResolver(templateResolver);
        }
    
        public String getTemplate(String templateName, Map<String, Object> parameters) {
            Context ctx = new Context();
            if (parameters != null) {
                parameters.forEach((k, v) -> {
                    ctx.setVariable(k, v);
                });
            }
            return this.templateEngine.process(templateName, ctx).trim();
        }
    
    }
    

    然后可以为 HTML 模板调用如下:

    HashMap<String, Object> values = new HashMap<>();
    values.put("hello", "hello everyone");
    GenericTemplateEngine engine = new GenericTemplateEngine(TemplateMode.HTML);
    String s = engine.getTemplate("hello_world.html", values);
    System.out.println(s);
    

    Map 中的值被加载到 Thymeleaf 上下文中,然后与模板一起传递给引擎类。

    如果您有一个文本模板而不是 HTML 模板,那么您将使用以下内容:

    new GenericTemplateEngine(TemplateMode.TEXT);
    

    【讨论】:

      【解决方案2】:

      您需要创建一个百里香模板mytemplate.html,其中包含:

      <h1 th:text="Hi ${first_name} ${last_name}"></h1>
      

      并将其与在模型中设置变量的 mvc 控制器一起使用:

      @Controller
      public class HelloController {
      
          @GetMapping("/hello")
          public String handle(Model model) {
              model.addAttribute("first_name", "Abel");
              model.addAttribute("last_name", "Lincon");
              return "mytemplate"; //resolves to mytemplate.html
          }
      }
      

      它会渲染&lt;h1&gt;Hi Abel Lincon&lt;/h1&gt;

      如果你想手动处理一个模板,你可以自动装配模板引擎并手动使用它:

      @Autowired SpringTemplateEngine templateEngine;
      
      String emailContent = templateEngine.process( "mytemplate",
                              new Context( Locale.ENGLISH, Map.of(
                                      "first_name", "Abel",
                                      "last_name", "Lincon"
                              )) );
      

      【讨论】:

      • 是否可以在没有 HTML 文件的情况下实现 - 意思是使用问题中提到的字符串。
      • @mperle 你为什么要尝试使用字符串?主要用途是具有可以在浏览器中显示的优势的 html 文件(百里香模板是有效的 html)
      • 正确。场景是我们需要处理 html 字符串并将处理后的字符串作为电子邮件正文发送。
      • cdalxndr,这有助于我正在寻找的场景。
      猜你喜欢
      • 1970-01-01
      • 2016-01-27
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 2016-01-30
      • 2021-10-10
      • 2019-02-20
      • 1970-01-01
      相关资源
      最近更新 更多