Thymeleaf

说声你好!在5分钟内扩展Thymeleaf

扩展Thymeleaf非常简单:我们只需要创建一个方言(dialect)并将其添加到我们的模板引擎中。让我们看看具体怎么操作。

此处展示的所有代码都来自一个可运行的应用程序。你可以查看或下载源代码其 GitHub 仓库.

方言(Dialects)

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

  • 处理逻辑通过处理器(processors)指定,并应用于我们标签中的属性(或者标签本身)。
  • 预处理和后处理逻辑通过预处理器(pre-processors)和后处理器(post-processors)来指定,并在实际处理发生之前(预处理)或之后(后处理)应用于我们的模板。
  • 表达式对象(Expression objects)这些对象可以用在Thymeleaf的标准表达式中(例如#arrays, #dates,等等),以便执行我们可能需要的特定操作。

所有这些功能都是可选的,一个方言可以只定义其中的一部分。例如,某个方言可能不需要定义任何处理器,但可以声明几个表达式对象.

如果你见过用标准方言(Standard Dialects)编写的代码片段,你应该已经注意到,可处理的属性是以th:开头的。这个“th”被称为方言前缀(dialect prefix),它意味着该方言处理的所有标签和属性都将以前述前缀开头。每个方言都可以指定自己的前缀。

另外需要注意的是,一个模板引擎可以同时设置多个方言,从而允许处理包含所有指定方言功能的模板(可以把方言想象成一种增强版的JSP标签库(JSP taglibs))。不仅如此,其中一些方言还可以共享前缀,从而有效地表现得像是一个聚合方言一样。

最简单的方言示例:Say Hello!

让我们为其中一个应用创建一个方言。这将是一个Spring MVC应用,因此我们已经在使用SpringStandard方言(更多细节请参阅Thymeleaf + Spring 教程)。但我们想添加一个新的属性,使我们可以向任何人打招呼,如下所示:

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

处理器(The processor)

首先,我们必须创建负责显示问候语的属性处理器。

所有处理器都实现了org.thymeleaf.processor.IProcessor接口,而具体的标签处理器则实现org.thymeleaf.processor.element.IElementTagProcessor接口,因为它是一个应用于元素(element)的处理器(按照XML/HTML术语),更确切地说是应用于该元素的open tag

此外,这是一个由该开始标签中的特定属性触发的处理器(open tag (hello:sayto),因此我们将继承一个有用的抽象类,它能为我们提供大部分所需的类结构:org.thymeleaf.processor.element.AbstractAttributeTagProcessor.

public class SayToAttributeTagProcessor extends AbstractAttributeTagProcessor {

    private static final String ATTR_NAME = "sayto";
    private static final int PRECEDENCE = 10000;


    public SayToAttributeTagProcessor(final String dialectPrefix) {
        super(
            TemplateMode.HTML, // This processor will apply only to HTML mode
            dialectPrefix,     // Prefix to be applied to name for matching
            null,              // No tag name: match any tag name
            false,             // No prefix to be applied to tag name
            ATTR_NAME,         // Name of the attribute that will be matched
            true,              // Apply dialect prefix to attribute name
            PRECEDENCE,        // Precedence (inside dialect's precedence)
            true);             // Remove the matched attribute afterwards
    }


    protected void doProcess(
            final ITemplateContext context, final IProcessableElementTag tag,
            final AttributeName attributeName, final String attributeValue,
            final IElementTagStructureHandler structureHandler) {

        structureHandler.setBody(
                "Hello, " + HtmlEscape.escapeHtml5(attributeValue) + "!", false);

    }


}

方言类(The dialect class)

创建处理器非常简单,但现在我们需要创建方言类(dialect class),它将告诉Thymeleaf我们的处理器是可用的。

最基础的方言接口org.thymeleaf.dialect.IDialect,只是告诉Thymeleaf某个类是一个方言(dialect)。但引擎需要知道这个方言能够提供什么功能,为了声明这一点,方言类将实现一组IDialect子接口(sub-interfaces)中的一个或多个。

具体来说,我们的方言将提供*处理器*,因此它会实现org.thymeleaf.dialect.IProcessorDialect。并且为了简化开发,我们不会直接实现这个接口,而是继承一个名为org.thymeleaf.dialect.AbstractProcessorDialect:

public class HelloDialect extends AbstractProcessorDialect {

    public HelloDialect() {
        super(
                "Hello Dialect",    // Dialect name
                "hello",            // Dialect prefix (hello:*)
                1000);              // Dialect precedence
    }

    
    /*
     * Initialize the dialect's processors.
     *
     * Note the dialect prefix is passed here because, although we set
     * "hello" to be the dialect's prefix at the constructor, that only
     * works as a default, and at engine configuration time the user
     * might have chosen a different prefix to be used.
     */
    public Set<IProcessor> getProcessors(final String dialectPrefix) {
        final Set<IProcessor> processors = new HashSet<IProcessor>();
        processors.add(new SayToAttributeTagProcessor(dialectPrefix));
        return processors;
    }


}

使用hello方言(Using the hello dialect)

使用我们的新方言非常简单。对于一个Spring MVC应用来说,只需在配置过程中将其添加到templateEnginebean中即可。

@Bean
public SpringTemplateEngine templateEngine(){
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    templateEngine.setEnableSpringELCompiler(true);
    templateEngine.setTemplateResolver(templateResolver());
    templateEngine.addDialect(new HelloDialect());
    return templateEngine;
}

注意,我们使用了addDialect(...)(而不是setDialect(...)),这意味着我们告诉引擎除了默认的方言之外还要使用我们的新方言。并且要额外使用默认的StandardDialect方言,因此所有的标准th:*属性也仍然可用。

现在我们的新属性就可以无缝工作了:

<p>Hello World!</p>

想要了解更多吗?

然后请查看“再次说你好!再花五分钟进一步扩展Thymeleaf”.

无噪 Logo
无噪文档
中文文档 · 复刻官网
查看所有 ↗