Skip to content

片段表达式语法

片段表达式(~{...})的语法规则非常清晰,主要有三种格式,覆盖了不同的片段引用场景:

1. 核心格式:~{模板名::选择器}

这是最常用的格式,含义是「在名为 模板名 的模板中,通过标记选择器(Markup Selector) 匹配并引入对应的片段」。注意:这里的「选择器」可以是简单的片段名(即 th:fragment 定义的名称),比如之前的 ~{footer :: copy} 就是这种情况;

INFO

标记选择器(Markup Selector)语法由底层的 AttoParser 解析库定义,其语法风格与 XPath 表达式或 CSS 选择器相近。更多相关信息可参见附录 C。 比如:

html
<!-- 引入 footer.html 中 class 为 "copyright" 的 div 元素 -->
<div th:insert="~{footer :: div.copyright}"></div>

2. 简化格式:~{模板名}

直接引入指定模板的完整内容,无需指定片段或选择器。

INFO

⚠️ 注意:模板名必须能被当前模板引擎的「模板解析器(Template Resolver)」解析(比如默认解析 /WEB-INF/templates/ 下的文件)。

html
<!-- 引入 header.html 的全部内容 -->
<div th:insert="~{header}"></div>

3. 同模板引用:~{::选择器} / ~{this::选择器}

当前模板中匹配选择器对应的片段(两种写法等价)。如果当前模板中未找到,会向上遍历模板调用栈(比如嵌套引入的模板),直到根模板中匹配到为止。

html
<!-- 引入当前模板中名为 "sidebar" 的片段 -->
<div th:insert="~{::sidebar}"></div>
<!-- 等价写法 -->
<div th:insert="~{this::sidebar}"></div>

模板名和选择器都可以是「完整的表达式」(甚至条件表达式),实现动态选择要引入的片段:

html
<!-- 根据用户是否为管理员,动态引入不同的页脚片段 -->
<div th:insert="~{ footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser}) }"></div>
  • ${user.isAdmin}:判断用户是否为管理员;
  • #{footer.admin}/#{footer.normaluser}:从国际化配置中读取不同的片段名(比如 footer.admin=admin-footer)。

片段中可以包含任意 th:* 属性:这些属性会在片段被引入到目标模板(即写有 th:insert/th:replace 的模板)时才执行计算; 片段可访问目标模板的上下文变量:片段中引用的变量(如 ${user}),会直接使用目标模板中的上下文变量,无需额外传递。

INFO

这种片段引用方式的一大优势是:片段文件本身可以是浏览器能正常显示的完整 HTML 页面(有完整的 <html>/<body> 等结构),既能作为独立页面预览,又能被 Thymeleaf 拆分为片段引入到其他模板中——完美兼顾「静态原型预览」和「动态模板复用」。

总结

  1. 片段表达式有三种核心格式:~{模板名::选择器}(跨模板选片段)、~{模板名}(引入完整模板)、~{::选择器}(同模板选片段);
  2. 模板名/选择器支持动态表达式(如条件判断),可实现按需引入不同片段;
  3. 片段中的 th:* 属性在引入时执行,且能访问目标模板的上下文变量;
  4. 片段文件可保留完整 HTML 结构,兼顾静态预览和动态复用。