扩展Thymeleaf很容易:只需要创建一个方言并将其添加到模板引擎。 下面来看看,如何一步步地实现。

所有在这里看到的代码都来自一个工作应用程序。可以从GitHub仓库查看或下载源代码

1. 方言

Thymeleaf方言(Dialects)是可以在模板中使用的一组功能。 这些功能包括:

  • 处理逻辑 - 通过适用于标签中的属性的处理器(或标签本身)指定处理逻辑。
  • 预处理和后处理逻辑通过预处理器和后处理器指定,实际上在处理之前(之前)或之后(后处理)应用于模板。
  • 表达式对象可用于Thymeleaf标准表达式(如#array#dates等),以执行可能需要的操作。 所有这些功能都是可选的,方言只能指定其中的一部分。 例如,一个方言可能不需要指定任何处理器,但是可以声明几个表达式对象。

如果已经看到用标准方言编写的代码片段,应该注意到,可处理的属性以th:开头。 这个“th”被称为方言前缀,这意味着由该方言处理的所有标签和属性将以这样的前缀开头。 每种方言都可以指定自己的前缀。

同样重要的是要注意,一个模板引擎可以一次设置多个方言,从而允许处理包括来自所有指定方言的特征的模板(将方言看作是一种JSP标签库)。 更重要的是,这些方言中的一些可以共享前缀,有效地作为一种方言。

2. 最简单的方言

这里将在应用程序中创建一个方言。 这将是一个Spring MVC应用程序,所以将要已经使用SpringStandard方言(更多细节参见Thymeleaf + Spring教程)。 但是想添加一个新的属性,向请求的客户端显示问候语,如下所示:

  1. <p hello:sayto="World">Hi ya!</p>

2.1 处理器

首先,需要创建属性处理器来处理显问候语消息。

所有处理器都实现org.thymeleaf.processor.IProcessor接口,特别是标记处理器实现org.thymeleaf.processor.element.IElementTagProcessor接口,因为它是一个处理器,它适用于元素(以XML/HTML术语),这种元素的开放标签。

另外,这个处理器会被这个开放标签(hello:sayto)中的指定属性触发,所以将扩展一个有用的抽象类,它将给出大部分的类基础结构:org.thymeleaf.processor.element.AbstractAttributeTagProcessor。请参考下面代码的实现 -

  1. public class SayToAttributeTagProcessor extends AbstractAttributeTagProcessor {
  2.  
  3. private static final String ATTR_NAME = "sayto";
  4. private static final int PRECEDENCE = 10000;
  5.  
  6. public SayToAttributeTagProcessor(final String dialectPrefix) {
  7. super(
  8. TemplateMode.HTML, // This processor will apply only to HTML mode
  9. dialectPrefix, // Prefix to be applied to name for matching
  10. null, // No tag name: match any tag name
  11. false, // No prefix to be applied to tag name
  12. ATTR_NAME, // Name of the attribute that will be matched
  13. true, // Apply dialect prefix to attribute name
  14. PRECEDENCE, // Precedence (inside dialect's precedence)
  15. true); // Remove the matched attribute afterwards
  16. }
  17.  
  18. protected void doProcess(
  19. final ITemplateContext context, final IProcessableElementTag tag,
  20. final AttributeName attributeName, final String attributeValue,
  21. final IElementTagStructureHandler structureHandler) {
  22.  
  23. structureHandler.setBody(
  24. "Hello, " + HtmlEscape.escapeHtml5(attributeValue) + "!", false);
  25.  
  26. }
  27. }

2.2 方言类

创建处理器非常简单,但现在还需要创建方言类,负责告诉Thymeleaf处理器是可用的。

最基本的方言接口:org.thymeleaf.dialect.IDialect只告诉Thymeleaf一个特定的类是方言。 但是引擎需要知道那个创建的方言能够提供什么,并且声明方言类,需要实现一组或几组IDialect子接口。

具体来说,out方言将提供*处理器,因此它将实现org.thymeleaf.dialect.IProcessorDialect。 为了更容易一些,这里不是直接实现接口,而是扩展一个名为org.thymeleaf.dialect.AbstractProcessorDialect的抽象类,参考以下代码:

  1. public class HelloDialect extends AbstractProcessorDialect {
  2.  
  3. public HelloDialect() {
  4. super(
  5. "Hello Dialect", // Dialect name
  6. "hello", // Dialect prefix (hello:*)
  7. 1000); // Dialect precedence
  8. }
  9.  
  10. /*
  11. * Initialize the dialect's processors.
  12. *
  13. * Note the dialect prefix is passed here because, although we set
  14. * "hello" to be the dialect's prefix at the constructor, that only
  15. * works as a default, and at engine configuration time the user
  16. * might have chosen a different prefix to be used.
  17. */
  18. public Set<IProcessor> getProcessors(final String dialectPrefix) {
  19. final Set<IProcessor> processors = new HashSet<IProcessor>();
  20. processors.add(new SayToAttributeTagProcessor(dialectPrefix));
  21. return processors;
  22. }
  23. }

3. 使用Hello方言

使用上面创建这个新方言非常简单。 这是一个Spring MVC应用程序,只需在配置期间将它添加到templateEngine Bean。如下代码所示 -

  1. @Bean
  2. public SpringTemplateEngine templateEngine(){
  3. SpringTemplateEngine templateEngine = new SpringTemplateEngine();
  4. templateEngine.setEnableSpringELCompiler(true);
  5. templateEngine.setTemplateResolver(templateResolver());
  6. templateEngine.addDialect(new HelloDialect());
  7. return templateEngine;
  8. }

请注意,通过使用addDialect(),而不是setDialect(),告诉引擎除了默认的StandardDialect之外,还想使用新的方言。 所以所有的标准th:*属性也将可用。

现在需要新属性可以无缝工作,如下:

  1. <p>Hello World!</p>