深色模式
片段表达式语法
片段表达式(~{...})的语法规则非常清晰,主要有三种格式,覆盖了不同的片段引用场景:
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 拆分为片段引入到其他模板中——完美兼顾「静态原型预览」和「动态模板复用」。
总结
- 片段表达式有三种核心格式:
~{模板名::选择器}(跨模板选片段)、~{模板名}(引入完整模板)、~{::选择器}(同模板选片段); - 模板名/选择器支持动态表达式(如条件判断),可实现按需引入不同片段;
- 片段中的
th:*属性在引入时执行,且能访问目标模板的上下文变量; - 片段文件可保留完整 HTML 结构,兼顾静态预览和动态复用。
