1. 简介

Thymeleaf 是一个强大的 Java 模板引擎,专门用于处理和生成 HTML、XML、JavaScript、CSS 和纯文本。关于 Thymeleaf 与 Spring 的基础集成,可以参考这篇入门指南

本文将聚焦模板布局——这是所有复杂网站必须面对的核心问题。简单来说,页面需要共享公共组件(如页眉、页脚、菜单等)。

Thymeleaf 通过自定义方言(dialect)解决这个问题,提供两种方案:

  • Thymeleaf 标准布局系统
  • 布局方言(Layout Dialect)(采用装饰器模式)

本文重点讲解 Thymeleaf 布局方言GitHub 地址)的核心功能,包括:

  • 布局创建
  • 自定义标题
  • head 元素合并

2. Maven 依赖

首先配置 Thymeleaf 与 Spring 的集成。核心依赖是 thymeleaf-spring

⚠️ 注意:Spring 4 项目需使用 thymeleaf-spring4 而非 thymeleaf-spring5。最新版本可在Maven 中央仓库获取。

布局方言的额外依赖:

<dependency>
    <groupId>nz.net.ultraq.thymeleaf</groupId>
    <artifactId>thymeleaf-layout-dialect</artifactId>
    <version>2.4.1</version>
</dependency>

最新版本参见Maven 中央仓库

3. Thymeleaf 布局方言配置

本节说明如何启用布局方言。如需了解 Thymeleaf 3.0 基础配置,参考这篇教程

添加 Maven 依赖后,需将方言注册到模板引擎:

Java 配置方式

SpringTemplateEngine engine = new SpringTemplateEngine();
engine.addDialect(new LayoutDialect());

XML 配置方式

<bean id="templateEngine" class="org.thymeleaf.spring5.SpringTemplateEngine">
    <property name="additionalDialects">
        <set>
            <bean class="nz.net.ultraq.thymeleaf.LayoutDialect"/>
        </set>
    </property>
</bean>

3.1. 高级元素合并策略

默认行为:内容元素追加到布局元素之后。但实际开发中常需智能合并(如 JS 脚本分组、样式表集中)。

解决方案:使用分组策略(GroupingStrategy):

Java 配置

engine.addDialect(new LayoutDialect(new GroupingStrategy()));

XML 配置

<bean class="nz.net.ultraq.thymeleaf.LayoutDialect">
    <constructor-arg ref="groupingStrategy"/>
</bean>

效果:元素自动排序分组
自定义需求:实现 SortingStrategy 接口并注入

4. 命名空间与属性处理器

启用方言后,可使用 layout 命名空间和五大属性处理器:

  • decorate
  • title-pattern
  • insert
  • replace
  • fragment

创建布局模板(template.html):

<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
...
</html>

4.1. layout:fragment

定义可替换的模板区块:

<body>
    <header>
        <h1>新方言示例</h1>
    </header>
    <section layout:fragment="custom-content">
        <p>默认内容:页面内容放置区</p>
    </section>
    <footer>
        <p>我的自定义页脚</p>
        <p layout:fragment="custom-footer">默认页脚内容</p>
    </footer>
</body>

💡 关键点

  • custom-contentcustom-footer 是可替换区块
  • 必须提供默认内容(避免渲染时出错)

4.2. layout:decorate

指定装饰器模板:

<!DOCTYPE html>
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
  layout:decorate="~{template.html}">
<head>
<title>布局方言示例</title>
</head>
<body>
    <section layout:fragment="custom-content">
        <p>自定义内容替换区</p>
    </section>
    <footer>
        <p layout:fragment="custom-footer">自定义页脚内容</p>
    </footer>
</body>
</html>

🔍 工作原理

  • layout:decorate 指向布局模板
  • 同名片段自动替换(如 custom-content

4.3. layout:title-pattern

智能合并页面标题:

<title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">Baeldung</title>

效果

<title>Baeldung - 布局方言示例</title>

💡 适用场景

  • 面包屑导航
  • 保留网站品牌名

4.4. layout:insert 与 layout:replace

处理器 行为说明 使用场景
layout:insert 类似 th:insert,支持传递完整 HTML 复用复杂 HTML 结构
layout:replace 类似 th:replace,替换宿主标签 完全替换标签内容

5. 总结

本文介绍了 Thymeleaf 布局方言的核心实现方案:

关键要点

  1. 依赖配置:添加 thymeleaf-layout-dialect
  2. 方言注册:Java/XML 方式二选一
  3. 元素合并:默认追加 vs 分组策略
  4. 五大处理器
    • fragment:定义可替换区块
    • decorate:指定布局模板
    • title-pattern:智能标题合并
    • insert/replace:HTML 片段复用

升级提示

⚠️ 示例基于 Thymeleaf 3.0,迁移指南见官方文档

实践建议

  1. 测试顺序
    • 先浏览器端调试
    • 再验证 JUnit 测试用例
  2. 方案选择
    • 开箱即用:使用现成布局方言
    • 高度定制:实现自定义 SortingStrategy

完整代码参考GitHub 项目。根据实际需求选择合适方案,避免重复造轮子!


原始标题:Thymeleaf: Custom Layout Dialect