Thymeleaf 教程
Thymeleaf 是一個服務器端 Java 模板引擎,能夠處理 HTML、XML、CSS、JAVASCRIPT 等模板文件。Thymeleaf 模板可以直接當作靜態原型來使用,它主要目標是為開發者的開發工作流程帶來優雅的自然模板,也是 Java 服務器端 HTML5 開發的理想選擇。
1. 創建模板文件
創建一個 HTML 模板文件:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Index Page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="${message}">Welcome to BeiJing!</p>
</body>
</html>
通過<html xmlns:th="http://www.thymeleaf.org">
引入 Thymeleaf 命名空間。th:text
用於處理p
標簽體的文本內容。該模板文件直接在任何瀏覽器中正確顯示,瀏覽器會自動忽略它們不能理解的屬性th:text
。但這不是一個真正有效的 HTML5 文檔,因為 HTML5 規范是不允許使用th:*
這些非標准屬性的。我們可以切換到 Thymeleaf 的data-th-*
語法,以此來替換th:*
語法:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Index Page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p data-th-text="${message}">Welcome to BeiJing!</p>
</body>
</html>
HTML5 規范是允許data-*
這樣自定義的屬性的。th:*
和data-th-*
這兩個符號是完全等效且可以互換的。但為了簡單直觀和代碼的緊湊性,本文采用th:*
的表示形式。
2. 標准表達式語法
Thymeleaf 提供了非常豐富的標准表達式語法,總共有 8 大類:
- 簡單表達式
- 字面值
- 文本操作
- 算術運算
- 布爾運算
- 比較和相等
- 條件運算
- 無操作符
2.1 簡單表達式
語法 | 名稱 | 描述 | 作用 |
---|---|---|---|
${…} | Variable Expressions | 變量表達式 | 取出上下文變量的值 |
*{…} | Selection Variable Expressions | 選擇變量表達式 | 取出選擇的對象的屬性值 |
#{…} | Message Expressions | 消息表達式 | 使文字消息國際化,I18N |
@{…} | Link URL Expressions | 鏈接表達式 | 用於表示各種超鏈接地址 |
~{…} | Fragment Expressions | 片段表達式 | 引用一段公共的代碼片段 |
2.1.1 ${…}
@GetMapping("/standard-expression-syntax/variables")
public String variables(ModelMap model, HttpSession session) {
model.put("now", new Date());
model.put("message", "Welcome to BeiJing!");
session.setAttribute("user", new User("fanlychie", "男", 24));
... ...
}
通過變量表達式${}
取出上下文環境中的message
變量:
<!-- Welcome to BeiJing! -->
<p th:text="${message}"></p>
它相當於:
ctx.getVariable("message");
2.1.2 *{…}
變量表達式${}
是面向整個上下文的,而選擇變量表達式*{}
的上下文是父標簽(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>
2.1.3 #{…}
消息表達式可用於國際化文字信息。首先我們來了解一下 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>
2.1.4 @{…}
鏈接表達式@{}
是專門用來處理 URL 鏈接地址的。
絕對地址示例:
<!-- https://fanlychie.github.io -->
<p th:text="@{https://fanlychie.github.io}"></p>
頁面相對地址示例:
<!-- commons/base.html -->
<p th:text="@{commons/base.html}"></p>
上下文相對地址(相對於當前的服務)示例:
<!-- /css/mian.css -->
<p th:text="@{/css/mian.css}"></p>
服務器相對地址(相對於部署在同一個服務器中的不同服務)示例:
<!-- /image/upload -->
<p th:text="@{~/image/upload}"></p>
參數使用示例:
<!-- /css/mian.css?v=1.0 -->
<p th:text="@{/css/mian.css(v=1.0)}"></p>
<!-- /user/order?username=fanlychie -->
<p th:text="@{/user/order(username=${session.user.name})}"></p>
<!-- /user/order?username=fanlychie&status=PAIED -->
<p th:text="@{/user/order(username=${session.user.name},status='PAIED')}"></p>
<!-- /user/fanlychie/info -->
<p th:text="@{/user/{username}/info(username=${session.user.name})}"></p>
2.1.5 ~{…}
片段表達式~{}
可以用來引用一段公共的 HTML 代碼片段。
語法 | 描述 |
---|---|
~{templatename} | 引用整個模板文件的代碼片段 |
~{templatename :: selector} | selector 可以是 th:fragment 指定的名稱或其他選擇器。 如類選擇器、ID選擇器等 |
~{::selector} | 相當於 ~{this :: selector},表示引用當前模板定義的代碼片段 |
在 Thymeleaf 模板文件中,你可以使用th:fragment
屬性來定義一段公共的代碼片段,然后你可以通過使用th:insert
、th:replace
、th:include
(Thymeleaf 3.0 開始不再推薦使用,本文也將不再介紹它)屬性來將這些公共的代碼片段引入到模板文件中來。
src/main/resources/templates/base.html,通過th:fragment
屬性定義一段公共的代碼片段:
<div id="footer" th:fragment="footerFragment">© 2017 fanlychie</div>
src/main/resources/templates/index.html,通過th:insert
屬性引用一段公共的代碼片段:
<div th:insert="~{base :: footerFragment}"></div>
其中,~{}
是可選的,我們可以去掉這層的包裹:
<div th:insert="base :: footerFragment"></div>
若 index.html 與 base.html 不在同級目錄,如 templates/commons/base.html:
<div th:insert="~{commons/base :: footerFragment}"></div>
使用th:fragment
屬性定義代碼片段時,你還可以聲明一組參數:
<div th:fragment="crumbs(parent, child)">
<i th:text="${parent}"></i> <i th:text="${child}"></i>
</div>
<!--
<i>用戶中心</i>
<i>我的訂單</i>
-->
<div th:insert="::crumbs('用戶中心', '我的訂單')"></div>
此外,我們還可以通過類選擇器、ID選擇器等來引用公共的代碼片段:
<div th:insert="~{base :: #footer}"></div>
除了th:insert
屬性th:replace
也可以用來引用公共的代碼片段。不同的是,th:insert
是直接將代碼片段插入到標簽體內,而th:replace
則是用代碼片段直接替換標簽體內容。
<!--
<div>
<div id="footer">© 2017 fanlychie</div>
</div>
-->
<div th:insert="~{base :: footerFragment}"></div>
<!--
<div id="footer">© 2017 fanlychie</div>
-->
<div th:replace="~{base :: footerFragment}"></div>
2.1.6 內置對象
對象 | 描述 |
---|---|
#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 |
#ctx
示例:
<!-- zh_CN -->
<p th:text="${#ctx.getLocale()}"></p>
<!-- Welcome to BeiJing! -->
<p th:text="${#ctx.getVariable('message')}"></p>
<!-- true -->
<p th:text="${#ctx.containsVariable('message')}"></p>
#vars
示例:
<!-- zh_CN -->
<p th:text="${#vars.getLocale()}"></p>
<!-- Welcome to BeiJing! -->
<p th:text="${#vars.getVariable('message')}"></p>
<!-- true -->
<p th:text="${#vars.containsVariable('message')}"></p>
#locale
示例:
<!-- zh_CN -->
<p th:text="${#locale}"></p>
<!-- CN -->
<p th:text="${#locale.country}"></p>
<!-- 中國 -->
<p th:text="${#locale.displayCountry}"></p>
<!-- zh -->
<p th:text="${#locale.language}"></p>
<!-- 中文 -->
<p th:text="${#locale.displayLanguage}"></p>
<!-- 中文 (中國) -->
<p th:text="${#locale.displayName}"></p>
#request
示例:
<!-- HTTP/1.1 -->
<p th:text="${#request.protocol}"></p>
<!-- http -->
<p th:text="${#request.scheme}"></p>
<!-- localhost -->
<p th:text="${#request.serverName}"></p>
<!-- 8080 -->
<p th:text="${#request.serverPort}"></p>
<!-- GET -->
<p th:text="${#request.method}"></p>
<!-- /standard-expression-syntax/variables -->
<p th:text="${#request.requestURI}"></p>
<!-- http://localhost:8080/standard-expression-syntax/variables -->
<p th:text="${#request.requestURL}"></p>
<!-- /standard-expression-syntax/variables -->
<p th:text="${#request.servletPath}"></p>
<!-- java.util.Collections$3@203646fe -->
<p th:text="${#request.parameterNames}"></p>
<!-- {q=[Ljava.lang.String;@3308c69f} -->
<p th:text="${#request.parameterMap}"></p>
<!-- q=expression -->
<p th:text="${#request.queryString}"></p>
注意,請求地址的 URL 參數直接通過#request.x
是取不出來的,需要使用param.x
語法來取出。如,URL:/standard-expression-syntax/variables?q=expression
,取出 q 參數的正確姿勢:
<p th:text="${param.q}"></p>
#response
示例:
<!-- 200 -->
<p th:text="${#response.status}"></p>
<!-- 8192 -->
<p th:text="${#response.bufferSize}"></p>
<!-- UTF-8 -->
<p th:text="${#response.characterEncoding}"></p>
<!-- text/html;charset=UTF-8 -->
<p th:text="${#response.contentType}"></p>
#session
示例:
<!-- 2BCB2A0EACFF2D9D249D9799431B5127 -->
<p th:text="${#session.id}"></p>
<!-- 1499786693244 -->
<p th:text="${#session.lastAccessedTime}"></p>
<!-- fanlychie -->
<p th:text="${#session.getAttribute('user').name}"></p>
注意,放到會話里面的對象直接通過#session.x
是取不出來的,需要使用session.x
語法來取出。如,取出會話里面的 user 對象的正確姿勢:
<p th:text="${session.user.name}"></p>
2.1.7 工具類
對象 | 描述 |
---|---|
#messages | 消息工具類,與 #{…} 作用相同 |
#uris | 地址相關的工具類 |
#conversions | 對象轉換工具類 |
#dates | 日期時間工具類 |
#calendars | 日歷工具類 |
#numbers | 數字工具類 |
#strings | 字符串工具類 |
#objects | 對象工具類 |
#bools | 布爾工具類 |
#arrays | 數組工具類 |
#lists | List 工具類 |
#sets | Set 工具類 |
#maps | Map 工具類 |
<!-- false -->
<p th:text="${#strings.isEmpty(message)}"></p>
<!-- 2017-07-12 00:37:25 -->
<p th:text="${#dates.format(now, 'yyyy-MM-dd HH:mm:ss')}"></p>
2.2 字面值
所謂字面值,首先它不是一個變量,它是一個具體的確切的值,通常這些值是比較簡單的,例如:18
、'welcome'
等,它們沒有名稱,以至於我們只能用值來稱呼它們,因此我們稱其為字面值。
2.2.1 文字字面值
文字字面值是用單引號引起來的任何字符內容,如果字符內容里面含有單引號,則需要進行轉義:
<!-- Welcome to BeiJing! -->
<p th:text="'Welcome to BeiJing!'"></p>
<!-- 'Welcome to BeiJing!' -->
<p th:text="'\'Welcome to BeiJing!\''"></p>
2.2.2 數字字面值
<!-- 2017 -->
<p th:text="2017"></p>
<!-- 2018 -->
<p th:text="2017 + 1"></p>
2.2.3 布爾字面值
<!-- false -->
<p th:text="1 > 2"></p>
<!-- 否 -->
<p th:text="1 > 2 ? '是' : '否'"></p>
2.2.4 空字面值
<!-- false -->
<p th:text="${user == null}"></p>
2.2.5 字面令牌
字面令牌(Literal Tokens)的內容只能含有(不能含有空格、特殊符號等):
- 大寫或小寫的字母、中文等不含空格和特殊符號的文本
- 0 到 9 的數字
- 中括號
- 下划線
- 連字符(-)
- 點符號(.)
實際上,數字、布爾和空字面值都是字面令牌的特殊情況。字面令牌能夠用來對標准表達式語法進行簡化,我們可以將包裹它的內容的單引號去掉:
<p th:text="Welcome to BeiJing!"></p>
它等效於:
<p th:text="'Welcome to BeiJing!'"></p>
2.3 文本操作
我們可以對文本內容進行兩種常用的操作,它們分別為字符串連接和字符串替換。
2.3.1 字符串連接
不管是字面值還是表達式的結果,我們都可以使用+
符號將它們連接起來:
<!-- Welcome to BeiJing! -->
<p th:text="'Welcome to ' + ${location} + '!'"></p>
2.3.2 字面值替換
符號||
可以用來將字面值和表達式包裹起來,這樣就能方便的替換變量的值,而不需要使用+
連接符:
<!-- Welcome to BeiJing! -->
<p th:text="|Welcome to ${location}!|"></p>
2.4 算術運算
支持+
(加)、-
(減)、*
(乘)、/
(除)、%
(模)運算:
<!-- 6 -->
<p th:text="4 + 2"></p>
<!-- 2 -->
<p th:text="4 - 2"></p>
<!-- 8 -->
<p th:text="4 * 2"></p>
<!-- 2 -->
<p th:text="4 / 2"></p>
<!-- 0 -->
<p th:text="4 % 2"></p>
<!-- 2 -->
<p th:text="${pagination.page + 1}"></p>
<!-- 2 -->
<p th:text="${pagination.page} + 1"></p>
2.5 布爾運算
支持and
(且)、or
(或)、!
(非)、not
(非)運算:
<p th:text="${user.online and user.vip}"></p>
<p th:text="${user.online or user.vip}"></p>
<p th:text="${!user.online}"></p>
<p th:text="${not user.online}"></p>
2.6 比較和相等
支持<
(lt
)、>
(gt
)、<=
(le
)、>=
(ge
)、==
(eq
)、!=
(ne
):
<p th:text="${user.age < 60}"></p>
<p th:text="${user.age <= 60}"></p>
<p th:text="${user.age > 18}"></p>
<p th:text="${user.age >= 18}"></p>
<p th:text="${user.age == 18}"></p>
<p th:text="${user.age != 18}"></p>
2.7 條件運算
三元運算符:(if) ? (then) : (else)
<p th:text="${user.online ? '在線' : '離線'}"></p>
<p th:text="${user.online ? (user.vip ? 'VIP用戶在線' : '普通用戶在線') : '離線'}"></p>
二元運算符:(value) ?: (defaultValue)
。
其中,value
非空(null)即真,條件為真時輸出value
,否則輸出defaultValue
。假設token = null
,user.email = fanlychie@gmail.com
<!-- 你還沒有登錄,請先登錄 -->
<p th:text="${token} ?: '你還沒有登錄,請先登錄'"></p>
<!-- fanlychie@gmail.com -->
<p th:text="${user.email} ?: '你還沒有綁定郵箱'"></p>
2.8 無操作符
當模板運行在服務器端時,Thymeleaf 會解析th:*
屬性的具體值替換標簽體的內容。無操作符(_
)則允許你使用原型標簽體的內容作為默認值:
<!-- 你還沒有登錄,請先登錄 -->
<p th:text="${token} ?: _">你還沒有登錄,請先登錄</p>
3. 使用文本
首先介紹兩個最基礎的th:*
屬th:text
和th:utext
,它們都是用於處理文本消息內容。
3.1 th:text
在標簽體中展示表達式評估結果的文本內容:
<p th:text="${message}"></p>
使用外部化的文本內容:
<p th:text="${message}">Welcome to BeiJing!</p>
當它作為靜態文件直接運行時,瀏覽器會自動忽略它不能識別的th:text
屬性,而顯示<p>
標簽體的文本內容Welcome to BeiJing!
當它作為模板文件運行在服務器端時,th:text
屬性的具體值將會替換<p>
標簽體的文本內容。
3.2 th:utext
屬性th:utext
與th:text
的區別在於:
th:text
默認會對含有 HTML 標簽的內容進行字符轉義;th:utext
(Unescaped Text)則不會對含有 HTML 標簽的內容進行字符轉義;
假設:message = "<b>Welcome to BeiJing!</b>"
。
使用th:text
屬性:
<p th:text="${message}"></p>
th:text
效果:Welcome to BeiJing!
使用th:utext
屬性:
<p th:utext="${message}"></p>
th:utext
效果:Welcome to BeiJing!
4. 設置屬性值
在 Thymeleaf 模板文件中,你可以使用th:*
(或者使用th:attr
屬性)來設置任意的 HTML5 標簽屬性的值。不僅如此,你還可以th:*-*
來同時為多個不同的標簽屬性設置相同的一個值,甚至你可以使用th:attrappend
和th:attrprepend
來追加新的值到現有的標簽屬性值中。
4.1 th:attr
這種方式是不被推薦的,了解一下就行。下面是用th:attr="href=..."
來設置標簽href
屬性的值:
<a th:attr="href=@{https://www.google.com.hk}">谷歌一下你就知道</a>
4.2 th:*
顯然th:attr="href=@{http://www.baidu.com}"
不夠簡潔,我們更推薦下面的這種語法:
<a th:href="@{https://www.google.com.hk}">谷歌一下你就知道</a>
其中th:*
中的*
可以是 HTML5 支持的任意屬性名稱,甚至這些屬性名稱可以是自定義的:
<!-- <div item-id="1001">Welcome to BeiJing!</div> -->
<div th:item-id="${user.id}">Welcome to BeiJing!</div>
4.3 th:-
如果想要同時為標簽的多個不同屬性設置相同的一個值,可以使用th:*-*
的語法:
<img src="logo.png" th:alt-title="LOGO圖片">
它相當於:
<img src="logo.png" th:alt="LOGO圖片" th:title="LOGO圖片">
4.4 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:classappend="..."
和th:styleappend=""
。
它們分別用來代替th:attrappend="class=..."
和th:attrappend="style=..."
。
<!-- <button class="btn enable">購買</button> -->
<button class="btn" th:classappend="${outOfStock} ? ' enable' : ' disable'">購買</button>
4.5 布爾屬性
在 HTML 中有些屬性是布爾屬性,布爾屬性是指沒有值的屬性,如readonly
、checked
、selected
等。它們若存在那就意味着值為 true。
<input type="checkbox" name="rememberme" checked /> 記住我
<input type="radio" name="sex" value="male" checked> 男
<input type="radio" name="sex" value="female"> 女
<input type="text" name="appId" value="J123654" readonly>
<select>
<option selected>北京</option>
<option>上海</option>
<option>廣州</option>
<option>深圳</option>
</select>
Thymeleaf 也允許我們通過th:*
(這里的*
表示任意的布爾屬性) 來選擇是否使用這些布爾屬性。
<input type="checkbox" name="rememberme" ch:checked="${rememberme}" /> 記住我
正如你所見,如果表達式的結果為true
,則自動勾選復選框,若為false
,則不會自動勾選。
5. 遍歷
遍歷(迭代)的語法th:each="自定義的元素變量名稱 : ${集合變量名稱}"
:
<div>
<spn>你所在城市:</spn>
<select name="mycity">
<option th:each="city : ${cities}" th:text="${city.name}"></option>
</select>
</div>
表格實例:
<table>
<tr th:each="book : ${books}">
<td th:text="${book.id}"></td>
<td th:text="${book.name}"></td>
<td th:text="${book.author}"></td>
...
</tr>
</table>
屬性th:each
提供了一個用於跟蹤迭代的狀態變量,它包含以下幾個屬性:
屬性 | 類型 | 描述 |
---|---|---|
index | int | 當前迭代的索引,從 0 開始 |
count | int | 當前迭代的計數,從 1 開始 |
size | int | 集合中元素的總個數 |
current | int | 當前的元素對象 |
even | boolean | 當前迭代的計數是否是偶數 |
odd | boolean | 當前迭代的計數是否是奇數 |
first | boolean | 當前元素是否是集合的第一個元素 |
last | boolean | 當前元素是否是集合的最后一個元素 |
狀態變量的使用語法:th:each="自定義的元素變量名稱, 自定義的狀態變量名稱 : ${集合變量名稱}"
:
<div>
<spn>所在城市:</spn>
<select name="mycity">
<option th:each="city, status : ${cities}" th:text="${city.name}" th:item-index="${status.count}"></option>
</select>
</div>
不管什么時候,Thymeleaf 始終會為每個th:each
創建一個狀態變量,默認的狀態變量名稱就是自定義的元素變量名稱后面加Stat
字符串組成:
<div>
<spn>所在城市:</spn>
<select name="mycity">
<option th:each="city : ${cities}" th:text="${city.name}" th:item-index="${cityStat.count}"></option>
</select>
</div>
6. 條件判斷
條件判斷語句有三種,分別是:th:if
、th:unless
、th:swith
。
6.1 th:if
當表達式的評估結果為真時則顯示內容,否則不顯示:
<a th:href="@{/user/order(uid=${user.id})}" th:if="${user != null}">我的訂單</a>
真假評估的依據:
- 當表達式的值不為空(null)時
- 如果表達式的值是一個布爾類型,且值為
true
評估為真,否則為假 - 如果表達式的值是一個數字類型,且值為非
0
評估為真,否則為假 - 如果表達式的值是一個字符類型,且值為非
0
評估為真,否則為假 - 如果表達式的值是一個字符串類型,且值為非
"false"
、"off"
、"no"
評估為真,否則為假 - 如果表達式的值不是一個
布爾
、數字
、字符
或字符串
評估為真
- 如果表達式的值是一個布爾類型,且值為
- 當表達式的值為空(null)時,評估結果為假
因此,上面代碼我們也可以簡寫成:
<a th:href="@{/user/order(uid=${user.id})}" th:if="${user}">我的訂單</a>
但是,為了代碼的可讀性,我們並不建議這樣使用。
6.2 th:unless
th:unless
與th:if
判斷恰好相反,當表達式的評估結果為假時則顯示內容,否則不顯示:
<a th:href="@{/user/order(uid=${user.id})}" th:unless="${user == null}">我的訂單</a>
6.3 th:swith
多路選擇語句,它需要搭配th:case
來使用:
<div th:switch="${user.role}">
<p th:case="admin">管理員</p>
<p th:case="user">普通用戶</p>
</div>
7. 定義局部變量
使用th:with
屬性可以定義局部變量:
<p th:with="name='fanlychie'">
<span th:text="${name}"></span>
</p>
同時定義多個局部變量時,用英文,
號分隔開:
<p th:with="name=${user.name},age={user.age}">
......
</p>
8. 注釋
下面介紹常見的兩種注釋:
8.1 標准注釋
語法:<!-- ... --->
,注釋的代碼塊會在文件源代碼中顯示出來。
8.1.1 單行注釋
<!-- <span>${message}</span> --->
8.1.2 多行注釋
<!--
<div th:switch="${user.role}">
<p th:case="admin">管理員</p>
<p th:case="user">普通用戶</p>
</div>
--->
8.2 解析器級注釋
語法:<!--/* ... */-->
,注釋的代碼塊會在引擎解析的時候抹去。
8.2.1 單行注釋:
<!--/* <span>${message}</span> */-->
8.2.2 多行注釋
<!--/*-->
<div th:switch="${user.role}">
<p th:case="admin">管理員</p>
<p th:case="user">普通用戶</p>
</div>
<!--*/-->
9. 內聯表達式
內聯表達式允許我們直接在 HTML 文本中使用標准表達式,而不需要使用th:*
標簽屬性。
9.1 [[…]]
[[]]
相當於th:text
,對含有 HTML 標簽的內容自動進行字符轉義。
<p>The message is : [[${htmlContent}]]</p>
9.2 [(…)]
[()]
相當於th:utext
,對含有 HTML 標簽的內容不進行字符轉義。
<p>The message is : [(${htmlContent})]</p>
9.3 th:inline
我們已經了解到,使用[[]]
和[()]
語法可以直接在 HTML 文本中使用標准表達式,如果想要使用更多高級的功能,需要使用th:inline
屬性來激活,它的取值如下:
值 | 描述 |
---|---|
none | 禁止內聯表達式,可以原樣輸出 [[]] 和 [()] 字符串 |
text | 文本內聯,可以使用 th:each 等高級語法 |
css | 樣式內聯,如:<style th:inline="css"> |
javascript | 腳本內聯,如:<style th:inline="javascript"> |
9.3.1 none
<!-- [[1, 2], [3, 4]] -->
<p th:inline="none">[[1, 2], [3, 4]]</p>
9.3.2 text
<!-- 北京 上海 廣州 深圳 -->
<p th:inline="text">
[# th:each="city : ${cities}"]
[(${city.name})]
[/]
</p>
9.3.3 css
<style th:inline="css">
body {
background-color:[[${bgColor}]];
}
</style>
9.3.4 javascript
<script th:inline="javascript">
var user = [[${user}]];
alert("用戶名:" + user.name);
</script>
擴展: 日期格式化
格式: ${#calendars.format(日期對象,格式)}
格式: 年-月-日 時:分:秒
Today is: <span th:text="${#calendars.format(today,'dd MMMM yyyy')}">13 May 2011</span>