-
什么是Thymeleaf
Thymeleaf 是一个服务器端 Java 模板引擎,可用于Web与非Web环境中的应用开发,能够处理 HTML5、HTML、XHTML、XML、JavaScript、CSS,甚至纯文本。
Thymeleaf也从一开始就设计了Web标准,特别是HTML5 。
-
使用方法
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org"><!--首先导入这行-->
<head>
<title>index</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="${message}">Hello World!</p>
</body>
</html>
th:text
用于处理p
标签体的文本内容。该模板文件直接在任何浏览器中正确显示,浏览器会自动忽略它们不能理解的属性th:text
。
我们可以切换到 Thymeleaf 的data-th-*
语法,以此来替换th:*
语法:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Index</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p data-th-text="${message}">Hello World!</p>
</body>
</html>
标准表达式语法:
总共有 8 大类:
- 简单表达式
- 字面值
- 文本操作
- 算术运算
- 布尔运算
- 比较和相等
- 条件运算
- 无操作符
语法 | 名称 | 描述 | 作用 |
---|---|---|---|
${…} | Variable Expressions | 变量表达式 | 取出上下文变量的值 |
*{…} | Selection Variable Expressions | 选择变量表达式 | 取出选择的对象的属性值 |
#{…} | Message Expressions | 消息表达式 | 使文字消息国际化,I18N |
@{…} | Link URL Expressions | 链接表达式 | 用于表示各种超链接地址 |
~{…} | Fragment Expressions | 片段表达式 | 引用一段公共的代码片段 |
变量表达式
变量表达式即OGNL表达式或Spring EL表达式(在Spring术语中也叫model attributes)。如下所示:
${session.user.name}
它们将以HTML标签的一个属性来表示:
<span th:text="${book.author.name}">
<li th:each="book : ${books}">
选择(星号)表达式
变量表达式${}
是面向整个上下文的,而选择变量表达式*{}
的上下文是父标签(th:object
)所选择的对象:
<div th:object="${session.user}">
<p th:text="*{name}"></p>
<p th:text="*{sex}"></p>
<p th:text="*{age}"></p>
</div>
它相当于:
<div>
<p th:text="${session.user.name}"></p>
<p th:text="${session.user.sex}"></p>
<p th:text="${session.user.age}"></p>
</div>
如果对象没有被选择,那么,*{}
和${}
表达式所达到的效果是完全相同的:
<p th:text="*{session.user.name}"></p>
<p th:text="${session.user.name}"></p>
文字国际化表达式
消息表达式可用于国际化文字信息。首先我们来了解一下 i18n 资源文件的命名规则:
- basename.properties
- basename_language.properties
- basename_language_country.properties
basename
是自定义的资源文件名称,language
和country
必须是 Java 支持的语言和国家。basename.properties
是缺省加载的资源文件,当客户端根据本地语言查找不到相关的资源文件时,则使用该配置文件。
创建文件src/main/resources/messages.properties
welcome.message = 北京欢迎你!
创建文件src/main/resources/messages_en_US.properties
welcome.message = Welcome to BeiJing!
在 IntelliJ IDEA 编辑视图:
messages
是 Spring Boot 加载资源文件默认采用的名称(basename
),如果你所使用的资源文件名称不是以messages
命名或所使用的资源文件不是在src/main/resources
根目录,你可以通过spring.messages.basename
属性来做具体的配置。如,资源文件messages.properties
和messages_en_US.properties
假设它们所在的目录位置是src/main/resources/i18n
。
application.properties 配置示例:
spring.messages.basename:i18n/messages
application.yml 配置示例:
spring
messages
basename: i18n/messages
静态文本消息示例:
<!-- 北京欢迎你! -->
<p th:text="#{welcom.message}"></p>
消息表达式#{}
是不允许直接处理非静态的文本消息的,但是你可以在资源文件中通过使用占位符{}
来处理非静态的文本消息:
messages.properties 配置示例:
welcome.user.message = {0}, 北京欢迎你!
messages_en_US.properties 配置示例:
welcome.user.message = {0}, Welcome to BeiJing!
非静态文本消息,以参数的形式传递变量的值:
<!-- fanlychie, 北京欢迎你! -->
<p th:text="#{welcome.user.message(${session.user.name})}"></p>
文字国际化表达式允许我们从一个外部文件获取区域文字信息(.properties),用Key索引Value,还可以提供一组参数(可选).
#{main.title}
#{message.entrycreated(${entryId})}
可以在模板文件中找到这样的表达式代码:
<table>
...
<th th:text="#{header.address.city}">...</th>
<th th:text="#{header.address.country}">...</th>
...
</table>
URL表达式
URL表达式指的是把一个有用的上下文或回话信息添加到URL,这个过程经常被叫做URL重写。
@{/order/list}
URL还可以设置参数:
@{/order/details(id=${orderId})}
相对路径:
@{../documents/report}
让我们看这些表达式:
<form th:action="@{/createOrder}">
<a href="main.html" th:href="@{/main}">
片段表达式
片段表达式~{}
可以用来引用一段公共的 HTML 代码片段。
语法 | 描述 |
---|---|
~{templatename} | 引用整个模板文件的代码片段 |
~{templatename :: selector} | selector 可以是 th:fragment 指定的名称或其他选择器。 如类选择器、ID选择器等 |
~{::selector} | 相当于 ~{this :: selector},表示引用当前模板定义的代码片段 |
内置对象
对象 | 描述 |
---|---|
#ctx | 上下文对象 |
#vars | 同 #ctx,表示上下文变量 |
#locale | 上下文本地化(特定的地理区域)变量,可参考 java.util.Locale |
#request | HttpServletRequest 对象,可参考 javax.servlet.http.HttpServletRequest |
#response | HttpServletResponse 对象,可参考 javax.servlet.http.HttpServletResponse |
#session | HttpSession 对象,可参考 javax.servlet.http.HttpSession |
#servletContext | ServletContext 对象,可参考 javax.servlet.ServletContext |
工具类
对象 | 描述 |
---|---|
#messages | 消息工具类,与 #{…} 作用相同 |
#uris | 地址相关的工具类 |
#conversions | 对象转换工具类 |
#dates | 日期时间工具类 |
#calendars | 日历工具类 |
#numbers | 数字工具类 |
#strings | 字符串工具类 |
#objects | 对象工具类 |
#bools | 布尔工具类 |
#arrays | 数组工具类 |
#lists | List 工具类 |
#sets | Set 工具类 |
#maps | Map 工具类 |
使用文本
首先介绍两个最基础的th:*
属th:text
和th:utext
,它们都是用于处理文本消息内容。
th:text
在标签体中展示表达式评估结果的文本内容:
<p th:text="${message}"></p>
当它作为静态文件直接运行时,浏览器会自动忽略它不能识别的th:text
属性,而显示<p>
标签体的文本内容Welcome to BeiJing!
<p th:text="${message}">Welcome to BeiJing!</p>
th:utext
属性th:utext
与th:text
的区别在于:
th:text
默认会对含有 HTML 标签的内容进行字符转义;th:utext
(Unescaped Text)则不会对含有 HTML 标签的内容进行字符转义。
设置属性值
在 Thymeleaf 模板文件中,你可以使用th:*
(或者使用th:attr
属性)来设置任意的 HTML5 标签属性的值。不仅如此,你还可以th:*-*
来同时为多个不同的标签属性设置相同的一个值,甚至你可以使用th:attrappend
和th:attrprepend
来追加新的值到现有的标签属性值中。
th:*-*
如果想要同时为标签的多个不同属性设置相同的一个值,可以使用th:*-*
的语法:
<img src="logo.png" th:alt-title="LOGO图片">
相当于
<img src="logo.png" th:alt="LOGO图片" th:title="LOGO图片">
th:attrappend & th:attrprepend
th:attrappend
和th:attrprepend
可以将表达式的结果分别追加到指定的属性值之后和之前。
<!-- <button class="btn enable">购买</button> -->
<button class="btn" th:attrappend="class=${outOfStock} ? ' enable' : ' disable'">购买</button>
<!-- <button class="enable btn">购买</button> -->
<button class="btn" th:attrprepend="class=${outOfStock} ? 'enable ' : 'disable '">购买</button>
遍历
遍历(迭代)的语法th:each="自定义的元素变量名称 : ${集合变量名称}"
:
<div>
<spn>你所在城市:</spn>
<select name="mycity">
<option th:each="city : ${cities}" th:text="${city.name}"></option>
</select>
</div>
属性th:each
提供了一个用于跟踪迭代的状态变量,它包含以下几个属性:
属性 | 类型 | 描述 |
---|---|---|
index | int | 当前迭代的索引,从 0 开始 |
count | int | 当前迭代的计数,从 1 开始 |
size | int | 集合中元素的总个数 |
current | int | 当前的元素对象 |
even | boolean | 当前迭代的计数是否是偶数 |
odd | boolean | 当前迭代的计数是否是奇数 |
first | boolean | 当前元素是否是集合的第一个元素 |
last | boolean | 当前元素是否是集合的最后一个元素 |
条件判断
条件判断语句有三种,分别是:th:if
、th:unless
、th:swith
。
th:if
当表达式的评估结果为真时则显示内容,否则不显示:
<a th:href="@{/user/order(uid=${user.id})}" th:if="${user != null}">我的订单</a>
th:unless
th:unless
与th:if
判断恰好相反,当表达式的评估结果为假时则显示内容,否则不显示:
<a th:href="@{/user/order(uid=${user.id})}" th:unless="${user == null}">我的订单</a>
th:swith
多路选择语句,它需要搭配th:case
来使用:
<div th:switch="${user.role}">
<p th:case="admin">管理员</p>
<p th:case="user">普通用户</p>
</div>
定义局部变量
使用th:with
属性可以定义局部变量:
<p th:with="name='fanlychie'">
<span th:text="${name}"></span>
</p>
[[…]]
[[]]
相当于th:text
,对含有 HTML 标签的内容自动进行字符转义。
<p>The message is : [[${htmlContent}]]</p>
[(…)]
[()]
相当于th:utext
,对含有 HTML 标签的内容不进行字符转义。
th:inline
我们已经了解到,使用[[]]
和[()]
语法可以直接在 HTML 文本中使用标准表达式,如果想要使用更多高级的功能,需要使用th:inline
属性来激活,它的取值如下:
值 | 描述 |
---|---|
none | 禁止内联表达式,可以原样输出 [[]] 和 [()] 字符串 |
text | 文本内联,可以使用 th:each 等高级语法 |
css | 样式内联,如:<style th:inline="css"> |
javascript | 脚本内联,如:<style th:inline="javascript"> |