Thymeleaf 是一种用于在服务器端和客户端之间渲染 HTML、XML、JavaScript、CSS 和文本的 Java 模板引擎。 模板引擎在 Web 领域的主要作用:让网站实现界面和数据分离,这样大大提高了开发效率,提供自然、灵活的模板处理功能,让代码重用更加容易。 官方支持:Spring Boot 提供对 Thymeleaf 的官方支持[1],做了很多默认配置,开发者只需编写对应 html 即可,大大减轻了上手难度和配置复杂度。 动静分离:Thymeleaf 选用 html 作为模板页,通过一些特定标签语法代表其含义,但并未破坏 html 结构,即使无网络、不通过后端渲染也能在浏览器成功打开,大大方便界面的测试和修改。 强大的表达式功能: Thymeleaf 支持强大的表达式语言(SpEL),可以在模板中执行复杂的表达式操作,如变量赋值、条件判断、迭代循环等。 易于集成:与 Spring Boot 框架紧密集成,提供了许多与 Spring Boot 相关的特性和扩展。它可以与 Spring MVC、Spring Security 等框架无缝集成。 应用广泛:Thymeleaf 是目前应用广泛的模板引擎之一,拥有活跃的社区和丰富的生态系统。它被广泛用于开发各种类型的 Web 应用和邮件模板。 1、添加 Thymeleaf 依赖 在项目的构建文件中添加 Thymeleaf 的相关依赖: 2、编写模板文件 创建一个以 通过使用 Thymeleaf 的标签和表达式,我们可以插入动态数据、进行条件判断、循环迭代等操作。 示例:引入 3、控制器中使用 Thymeleaf 在 Spring MVC 的控制器中,参数的值将添加到 如果你看过使用标准方言[2]编写的代码片段,你应该注意到可处理的属性都是以 th: 开头。 这个 还要注意的是,一个模板引擎可以同时设置多个方言,从而允许处理包含所有指定方言特性的模板(把方言视为一种类似 JSP 标签库的增强功能)。 其中一些方言可以共享前缀,实际上充当一个聚合方言的作用。 Thymeleaf 提供了许多 标准方言中的几个最基本的属性: 大多数 Thymeleaf 属性允许将其值设置为或包含表达式,由于它们使用的方言,我们将其称为标准表达式。 包含以下五种类型: 变量表达式用于在模板中访问和显示变量的值。 变量可以是通过控制器传递给模板的模型属性、请求参数、会话属性等。 1、访问自定义对象 2、访问内置对象 ① 访问请求对象: ② 访问请求参数: ③ 访问会话属性: 【注意】:${...} 变量表达式在模板中只能读取变量的值,不能修改变量的值。 选择表达式与变量表达式一样,将在选定的对象上执行,而不是在整个上下文变量映射上执行。 #{...} 是一种用于国际化(i18n)的消息表达式。它的主要目的是在软件中支持多语言的消息处理。 1、生成相对路径链接: 2、生成带参数的链接: 3、生成 URI 片段链接: 直接跳转到具有 ID 为 "section-1" 的页面片段。 【注意】: 通过 使用格式为: 常见属性: 1、包含模板片段: 定义了一个名为 使用 借助于标记选择器的强大功能,可以不使用任何 2、参数化片段: 使用 代码定义了一个名为 调用带参数的片段: 【注意】:片段表达式在 在Thymeleaf模板引擎中,字面量(Literals)和表达式操作(Operations)用于在模板中进行数据处理和计算。 这些表达式可以用于文本替换、条件判断、循环迭代等操作,从而使模板更具动态性和灵活性。 示例: 1、字符串字面量: 2、数字字面量: 3、变量引用: 4、算术操作: 5、逻辑操作: 表达式预处理(Expression Preprocessing)是一种用于对表达式进行预处理和修改的机制。可以使用预处理器在表达式求值之前对其进行操作和转换。 预处理器提供了一些特殊语法和功能,可以扩展表达式的功能并提供更好的灵活性和可读性。 预处理的具体用法: 1、转义表达式: 2、默认值设置: 3、集合选择: 4、字符串拼接: 【注意】:片段表达式在 Springboot 官方支持的模板引擎:Thymeleaf
Thymeleaf 的用法
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
dependencies {
implementation 'org.thymeleaf:thymeleaf:3.1.2.RELEASE'
}.html
为后缀的模板文件,在其中使用 Thymeleaf 的模板语法。www.thymeleaf.org
<p>
中 th:text="'Hello, ' + ${name} + '!'"
为 Thymeleaf 语法。 <!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'Hello, ' + ${name} + '!'" />
</body>
</html>Model
对象,传递给 Thymeleaf 模板
。 Thymeleaf 会自动根据模板中的表达式来渲染数据,并生成最终的 HTML
页面。package com.example.servingwebcontent;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class GreetingController {
@GetMapping("/greeting")
public String greeting(@RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
model.addAttribute("name", name);
return "greeting";
}
}如何使用标准方言
th
被称为方言前缀,它意味着所有由该方言处理的标签和属性都将以这个前缀开始。每个方言可以指定自己的前缀。基本属性
th
属性,用于评估表达式并将这些属性的值设置为其结果。 它们的名称与它们所设置的属性的名称相似,用来对应不同的 XHTML 和 HTML5 属性。// 替换了标签的主体
<p th:text="#{msg.welcome}">Welcome everyone!</p>
// 语法等同于 foreach
<li th:each="book : ${books}" th:text="${book.title}">En las Orillas del Sar</li>
// 提交表单时,浏览器将向 /createOrder 发送POST请求
<form th:action="@{/createOrder}" method="post">
// 使用表达式 #{form.submit} 的求值结果作为按钮的值
<input type="button" th:value="#{form.submit}" />
// 跳转到 /admin/users 地址
<a th:href="@{/admin/users}">
...Thymeleaf 标准表达式
${...} : Variable expressions.
<p th:text="${user.name}"></p>
${user.name}
表达式用于访问模型中名为 "user" 对象的 "name" 的属性,并将其值插入到 <p>
元素中。html <input id="requestURI" th:value="${#request.requestURI}"/>
Thymeleaf 文档[3] 中可通过 ${#ctx.request}
在上下文对象中获取 request,也可以通过简化形式 ${#request}
获得到 request。再通过 request 中的 requestURI 获得。html <p th:text="${param.email}"></p>
${param.email}
表达式用于获取名为 "email" 的请求参数的值,并将其插入到 <p>
元素中。html ${session.user}
${session.user}
表达式用于获取会话中名为 "user" 的属性的值,并将其插入到 <p>
元素中。*{...} : Selection expressions.
<div th:object="${user}">
<p th:text="${user.name}"></p>
<p th:text="*{age}"></p>
</div>${user}
是一个对象绑定到上下文变量中的用户对象。th:object
指令会将该对象设置为当前选择对象。 然后,我们可以使用选择表达式 *{age}
相当于 ${user.age}
来获取对象的属性值。#{...} : Message(i18n) expressions.
const name = 'Alice';
const greeting = `Hello, #{name}!`;
console.log(greeting);#{name}
表达式用来将变量 name 的值动态地插入到问候消息中,生成适当的本地化文本。@{...} : Link(URL) expressions.
@{...}
表达式是链接表达式(Link Expressions),用于生成动态链接(URL)。可以轻松地处理路由和参数传递,无需手动构建 URL。<a th:href="@{/home}">Home</a>
@{/home}
表达式将生成一个相对于当前上下文路径的链接,指向 "home" 路径。当用户点击链接时,将导航到 "/home" 页面。<a th:href="@{/user/details(userId=${user.id})}">View Details</a>
@{/user/details(userId=${user.id})}
表达式生成一个带有参数的链接。${user.id}
是一个变量表达式,表示用户的 ID。生成的链接将包含用户 ID 作为查询参数,例如: "/user/details?userId=123"。<a th:href="@{#section-1}">Go to Section 1</a>
Thymeleaf 3.0
及更高版本中引入。~{...} : Fragment expressions.
~{...}
表达式是片段表达式(Fragment Expressions)[4],用于引入和使用模板片段,重用可独立使用的模块或组件。 通过引入和参数化片段,在不同的地方使用相同的代码片段,提高了模板的可维护性和重用性。th:fragment
定义模板,然后用 th:insert
或 th:replace
使用定义的模板。{templatename::selector}
,应用于名为 templatename
的模板上的指定标记选择器所得到的片段。也可以使用:
~{templatename}
:包含名为 templatename 的完整模板。~{::selector} 或 ~{this::selector}
:插入与选择器匹配的来自同一个模板的片段。
copy
的片段:<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<footer th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</footer>
</body>
</html>th:insert
或 th:replace
属性在页面中包含该片段:<body>
<div th:insert="~{footer :: copy}"></div>
<div th:replace="~{footer :: copy}"></div>
</body>th:insert
或 th:replace
期望一个片段表达式(~{...}),它是一个返回片段的表达式。执行结果:<body>
<div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</body>th:fragment
属性的片段。通过 CSS
选择器的方式如:选择器 id
引用它。<div id="copy-section">
© 2011 The Good Thymes Virtual Grocery
</div><body>
<div th:insert="~{footer :: #copy-section}"></div>
</body>th:fragment
属性为片段定义参数,并调用带参数的片段。myFragment
的片段,接收两个参数 param1
和 param2
:<div th:fragment="myFragment (param1, param2)">
<p th:text="${param1} + ' - ' + ${param2}">...</p>
</div><div th:replace="~{ ::myFragment (${value1},${value2}) }">...</div>
<div th:replace="~{ ::myFragment (param1=${value1},param2=${value2}) }">...</div>th:replace="~{::myFragment (param1=${value1},param2=${value2})}"
这相当于 th:replace
和 th:with
的组合:<div th:replace="~{::myFragment}" th:with="param1=${value1},param2=${value2}">
Thymeleaf 3.0
及更高版本中引入。Literals and operations
<p th:text="'Hello, Thymeleaf!'"></p>
'Hello, Thymeleaf!'
是一个字符串字面量,可以在 <p>
元素中显示文本 "Hello, Thymeleaf!"。<p th:text="42"></p>
42
是一个数字字面量,可以在 <p>
元素中显示数字 42。<p th:text="${username}"></p>
${username}
是一个变量引用,通过该表达式可以获取名为 "username" 的变量的值,并在 <p>
元素中显示。<p th:text="${number1 + number2}"></p>
${number1 + number2}
是一个算术操作,通过该表达式可以对 number1 和 number2 变量进行加法运算,并在 <p>
元素中显示结果。<p th:if="${age >= 18}">You are an adult.</p>
${age >= 18}
是一个逻辑操作,通过该表达式可以判断 age 变量是否大于或等于 18,如果条件满足,则显示 "You are an adult."。Expression preprocessing
<p th:text="|Hello, ${name}!|"></p>
|${name}|
是一个转义表达式,通过在表达式外添加竖线字符 "|",可以防止表达式被求值,而直接显示为文本 "Hello, ${name}!"。<p th:text="${username} ?: 'Guest'"></p>
${username} ?: 'Guest'
是一个默认值设置,如果 username 变量为空或不存在,将使用默认值 "Guest"。<ul>
<li th:each="item : ${items}" th:text="${item.name}"></li>
</ul>${item.name}
是一个集合选择表达式,用于从 items 集合中选取每个元素的 name 属性并显示在列表项中。<p th:text="'Hello ' + ${name}"></p>
'Hello ' + ${name}
是一个字符串拼接表达式,可将字符串 "Hello " 和 name 变量的值进行拼接。Thymeleaf 3.0
及更高版本中引入。总结
Thymeleaf
是一种 Java 模板引擎,大大提高开发效率,提高代码复用率,拥有快速开发网页能力,掌握它还是很有必要的! 若想了解更多 Thymeleaf
,请到Thymeleaf 官网[5]深入学习。参考资料
Spring Boot 提供对 Thymeleaf 的官方支持: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#web.servlet.spring-mvc.template-engines
[2]
标准方言: https://www.thymeleaf.org/doc/articles/sayhelloextendingthymeleaf5minutes.html
[3]
Thymeleaf 文档: https://www.thymeleaf.org/doc/tutorials/3.1/usingthymeleaf.html#base-objects"
[4]
片段表达式(Fragment Expressions): https://www.thymeleaf.org/doc/tutorials/3.1/usingthymeleaf.html#template-layout"
[5]
Thymeleaf 官网: https://www.thymeleaf.org/doc/tutorials/3.1/usingthymeleaf.html#introducing-thymeleaf
发表评论