官方文檔(基于3.0版本)戴涝,基于springboot項目的滋戳,建議直接從第三章Using Texts開始查閱:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html
Thymeleaf是spring boot推薦使用的模板語法,除此之外常見的模板語法還有Freemarker和jsp喊括。jsp應該是java程序員最早接觸的模板引擎胧瓜,而Freemarker也很常見。
一.th屬性
常用th屬性解讀
html有的屬性郑什,Thymeleaf基本都有府喳,而常用的屬性大概有七八個。
1.th:text : 設置當前元素的文本內容蘑拯,相同功能的還有th:utext钝满,兩者的區(qū)別在于前者不會轉義html標簽兜粘,后者會。
2.th:value : 設置當前元素的value值弯蚜,類似修改指定html標簽屬性的還有th:src,th:href孔轴。
3.th:each : 遍歷循環(huán)元素,和th:text或th:value一起使用碎捺。注意該屬性修飾的標簽位置路鹰,詳細看后文。
4.th:if : 條件判斷收厨,類似的還有th:unless晋柱,th:switch,th:case诵叁。
5.th:insert : 代碼塊引入雁竞,類似的還有th:replace,th:include拧额,三者區(qū)別很大碑诉,若使用不恰當會破壞html結構,常用于公共代碼塊的提取復用侥锦。
6.th:fragment : 定義代碼塊进栽,方便被th:insert引用。
7.th:object : 聲明變量捎拯,一般和*{}一起配合使用泪幌,達到偷懶的效果。
- th:attr : 修改任意屬性署照,實際開發(fā)中用的較少祸泪,因為有豐富的其他th屬性幫忙。
常用th屬性使用
使用Thymeleaf屬性需要注意一下五點:
一.若要使用Thymeleaf語法建芙,首先要聲明名稱空間
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
二.設置文本內容th:text 没隘,設置input的值th:value ,循環(huán)輸出th:each 禁荸,條件判斷th:if右蒲,插入代碼塊th:insert,定義代碼塊th:fragment赶熟,聲明變量th:object
三.th:each 的用法需要格外注意瑰妄,打個比方:如果你要循環(huán)一個div中的p標簽,則th:each屬性必須放在p標簽上映砖。若你將th:each放在div上间坐,則循環(huán)的將是整個div。
四.變量表達式中提供了很多內置方法,該內置方法是用#開頭竹宋,請不要與#{}消息表達式弄混劳澄。
五.th:insert,th:replace,th:include三種插入代碼塊的效果相似,但區(qū)別很大蜈七。
舉個栗子秒拔,后續(xù)會詳細說明:
別忘了引入maven依賴,本文用的是springboot環(huán)境:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
項目結構:
<!DOCTYPE html>
<!--名稱空間-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymeleaf 語法</title>
</head>
<body>
<h2>hymeleaf 語法</h2>
<!--th:text 設置當前元素的文本內容飒硅,常用砂缩,優(yōu)先級不高-->
<p th:text="${thText}" />
<p th:utext="${thUText}"/>
<!--th:value 設置當前元素的value值,常用狡相,優(yōu)先級僅比th:text高-->
<input type="text" th:value="${thValue}" />
<!--th:object 聲明變量梯轻,和*{} 一起使用-->
<div th:object="${thObject}">
<p>ID: <span th:text="*{id}" /></p><!--th:text="${thObject.id}"-->
<p>TH: <span th:text="*{thName}" /></p><!--${thObject.thName}-->
<p>DE: <span th:text="*{desc}" /></p><!--${thObject.desc}-->
</div>
<!--th:each 遍歷列表,常用尽棕,優(yōu)先級很高,僅此于代碼塊的插入-->
<!--th:each 修飾在div上彬伦,則div層重復出現滔悉,若只想p標簽遍歷,則修飾在p標簽上-->
<div th:each="message : ${thEach}"> <!-- 遍歷整個div-p单绑,不推薦-->
<p th:text="${message}" />
</div>
<!--只遍歷p回官,推薦使用-->
<div>
<p th:each="user : ${ulist}" th:object="${user}">
<span th:text="*{id}"></span>
<span th:text="*{name}"></span>
<span th:text="*{phone}"></span>
</p>
</div>
<!--th:if 條件判斷,類似的有th:switch搂橙,th:case歉提,優(yōu)先級僅次于th:each, 其中#strings是變量表達式的內置方法-->
<p th:text="${thIf}" th:if="${not #strings.isEmpty(thIf)}"></p>
<!--th:insert 把代碼塊插入當前div中,優(yōu)先級最高区转,類似的有th:replace苔巨,th:include,~{} :代碼塊表達式 -->
<div th:insert="~{template/footer :: copy}"></div>
<div th:replace="~{template/footer :: copy}"></div>
<div th:include="~{template/footer :: copy}"></div>
</body>
</html>
后臺給負責給變量賦值废离,和跳轉頁面侄泽。
@RequestMapping("/admin")
public String toAdmin(Model model){
PageHelper.startPage(1,10);
PageHelper.orderBy("id desc");
List<InterUser> ulist = interUserService.selectInterUserList();
model.addAttribute("ulist",ulist);
model.addAttribute("thText","thText1");
model.addAttribute("thUText","thUText1");
model.addAttribute("thValue","thValue1");
model.addAttribute("thEach", Arrays.asList("th:each", "遍歷列表"));
model.addAttribute("thIf", "msg is not null");
model.addAttribute("thObject", new ThObject(1L, "th:object", "用來偷懶的th屬性"));
return "/admin/admin";
}
二.標準表達式語法
變量表達式:
${...}
鏈接表達式:
@{...}
消息表達式:
#{...}
代碼塊表達式:
~{...}
選擇變量表達式
*{...}
變量表達式使用頻率最高,其功能也是非常的豐富蜻韭。所以我們先從簡單的代碼塊表達式開始悼尾,然后是消息表達式,再是鏈接表達式肖方,最后是變量表達式闺魏,隨帶介紹選擇變量表達式。
~{...}代碼塊表達式
支持兩種語法
推薦:
~{templatename :: fragmentname}
支持:
~{templatename :: #id}
templatename : 模板名俯画,Thymeleaf會根據模板名解析完整路徑:/resources/templates/templatename.html析桥,要注意文件的路徑。
<div th:insert="~{template/footer :: copy}"></div>
<div th:replace="~{template/footer :: copy}"></div>
<div th:include="~{template/footer :: copy}"></div>
fragment : 片段名,Thymeleaf通過th:fragment聲明定義代碼塊烹骨,即th:fragment="fragmentname"
id : HTML的id選擇器翻伺,使用時要在前面加上#號,不支持class選擇器
代碼塊的聲明:
此項目中所有需要復用的html代碼塊為了統(tǒng)一都放入了/resources/templates/template/文件夾下
footer.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<footer th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</footer>
</body>
</html>
代碼塊表達式的使用
代碼塊表達式需要配合th屬性(th:insert沮焕,th:replace吨岭,th:include)一起使用。
th:insert:將代碼塊片段整個插入到使用了th:insert的HTML標簽中峦树,
th:replace:將代碼塊片段整個替換使用了th:replace的HTML標簽中辣辫,
th:include:將代碼塊片段包含的內容插入到使用了th:include的HTML標簽中,
用一個官方例子來區(qū)分三者的不同魁巩。
<!--三種不同的引入方式-->
<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div>
生成的html如下:
<!--th:insert是在div中插入代碼塊急灭,即多了一層div-->
<div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</div>
<!--th:replace是將代碼塊代替當前div,其html結構和之前一致-->
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
<!--th:include是將代碼塊footer的內容插入到div中谷遂,即少了一層footer-->
<div>
© 2011 The Good Thymes Virtual Grocery
</div>
#{...}消息表達式
消息表達式一般用于國際化的場景葬馋。結構:th:text="#{msg}"
@{...}鏈接表達式
鏈接表達式好處
不管是靜態(tài)資源的引用,form表單的請求肾扰,凡是鏈接都可以用@{...} 畴嘶。這樣可以動態(tài)獲取項目路徑,即便項目名變了集晚,依然可以正常訪問
#修改項目名窗悯,鏈接表達式會自動修改路徑,避免資源文件找不到
server.context-path=/emp
鏈接表達式結構
無參:
@{/xxxx}
有參:
@{/xxxx(k1=v1,k2=v2)}
//對應的url結構如下
xxxx?k1=v1&k2=v2
引入本地資源
@{/項目本地的資源路徑}
引入外部資源:
@{/webjars/資源在jar包中的路徑}
舉例:
<link th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet">
<link th:href="@{/main/css/itdragon.css}" rel="stylesheet">
<form class="form-login" th:action="@{/user/login}" th:method="post" >
<a class="btn btn-sm" th:href="@{/login.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/login.html(l='en_US')}">English</a>
${...}變量表達式
變量表達式有豐富的內置方法偷拔,使其更強大蒋院,更方便。
變量表達式功能
一莲绰、可以獲取對象的屬性和方法
二欺旧、可以使用ctx,vars钉蒲,locale切端,request,response顷啼,session踏枣,servletContext內置對象
三、可以使用dates钙蒙,numbers茵瀑,strings,objects躬厌,arrays马昨,lists竞帽,sets,maps等內置方法(重點介紹)
常用的內置對象
一鸿捧、ctx :上下文對象屹篓。
二、vars :上下文變量匙奴。
三堆巧、locale:上下文的語言環(huán)境。
四泼菌、request:(僅在web上下文)的 HttpServletRequest 對象谍肤。
五、response:(僅在web上下文)的 HttpServletResponse 對象。
六、session:(僅在web上下文)的 HttpSession 對象阎姥。
七、servletContext:(僅在web上下文)的 ServletContext 對象
這里以常用的Session舉例构资,用戶刊登成功后,會把用戶信息放在Session中,Thymeleaf通過內置對象將值從session中獲取。
// java 代碼將用戶名放在session中
session.setAttribute("userinfo",username);
// Thymeleaf通過內置對象直接獲取
th:text="${session.userinfo}"
常用的內置方法
一赋除、strings:字符串格式化方法,常用的Java方法它都有非凌。比如:equals,equalsIgnoreCase荆针,length敞嗡,trim,toUpperCase航背,toLowerCase喉悴,indexOf,substring玖媚,replace箕肃,startsWith,endsWith今魔,contains勺像,containsIgnoreCase等
二、numbers:數值格式化方法错森,常用的方法有:formatDecimal等
三吟宦、bools:布爾方法,常用的方法有:isTrue涩维,isFalse等
四殃姓、arrays:數組方法,常用的方法有:toArray,length蜗侈,isEmpty篷牌,contains,containsAll等
五踏幻、lists枷颊,sets:集合方法,常用的方法有:toList叫倍,size偷卧,isEmpty,contains吆倦,containsAll听诸,sort等
六、maps:對象方法蚕泽,常用的方法有:size晌梨,isEmpty,containsKey须妻,containsValue等
七仔蝌、dates:日期方法,常用的方法有:format荒吏,year敛惊,month,hour绰更,createNow等
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>Thymeleaf 內置方法</h2>
<h3>#strings</h3>
<div th:if="${not #strings.isEmpty(itdragonStr)}">
<p>Old Str : <span th:text="${itdragonStr}"></span></p>
<p>toUpperCase : <span th:text="${#strings.toUpperCase(itdragonStr)}"></span></p>
<p>toLowerCase : <span th:text="${#strings.toLowerCase(itdragonStr)}"></span></p>
<p>equals : <span th:text="${#strings.equals(itdragonStr,'itdragonblog')}"></span></p>
<p>equalsIgnoreCase : <span th:text="${#strings.equalsIgnoreCase(itdragonStr,'itdragonblog')}"></span></p>
<p>indexOf : <span th:text="${#strings.indexOf(itdragonStr,'r')}"></span></p>
<p>substring : <span th:text="${#strings.substring(itdragonStr,2,8)}"></span></p>
<p>replace : <span th:text="${#strings.replace(itdragonStr,'it','IT')}"></span></p>
<p>startsWith : <span th:text="${#strings.startsWith(itdragonStr,'it')}"></span></p>
<p>contains : <span th:text="${#strings.contains(itdragonStr,'IT')}"></span></p>
</div>
<h3>#numbers</h3>
<div>
<p>formatDecimal 整數部分隨意瞧挤,小數點后保留兩位,四舍五入:<span th:text="${#numbers.formatDecimal(itdragonNum,0,2)}"></span></p>
<p>formatDecimal 整數部分保留五位數儡湾,小數點保留兩位特恬,四舍五入:<span th:text="${#numbers.formatDecimal(itdragonNum,4,2)}"></span></p>
</div>
<h3>#bools </h3>
<div th:if="${#bools.isTrue(itdragonBool)}">
<p th:text="${itdragonBool}"></p>
</div>
<h2>#arrays </h2>
<div th:if="${not #arrays.isEmpty(itdragonArray)}">
<p>length : <span th:text="${#arrays.length(itdragonArray)}"></span></p>
<p>contains : <span th:text="${#arrays.contains(itdragonArray,5)}"></span></p>
<p>containsAll : <span th:text="${#arrays.containsAll(itdragonArray,itdragonArray)}"></span></p>
</div>
<h3>#lists </h3>
<div th:if="${not #lists.isEmpty(itdragonList)}">
<p>size : <span th:text="${#lists.size(itdragonList)}"></span></p>
<p>contains : <span th:text="${#lists.contains(itdragonList,0)}"></span></p>
<p>sort : <span th:text="${#lists.sort(itdragonList)}"></span></p>
</div>
<h3>#maps </h3>
<div th:if="${not #maps.isEmpty(itdragonMap)}">
<p>size : <span th:text="${#maps.size(itdragonMap)}"></span></p>
<p>containKey : <span th:text="${#maps.containsKey(itdragonMap,'thName')}"></span></p>
<p>containValue : <span th:text="${#maps.containsValue(itdragonMap,'#maps')}"></span></p>
<p><span th:text="${itdragonMap.thName}"></span></p>
</div>
<h3>#dates </h3>
<div>
<p>format : <span th:text="${#dates.format(itdragonDate)}"></span></p>
<p>custom format : <span th:text="${#dates.format(itdragonDate,'yyyy-MM-dd HH:mm:ss')}"></span></p>
<p>day : <span th:text="${#dates.day(itdragonDate)}"></span></p>
<p>month : <span th:text="${#dates.month(itdragonDate)}"></span></p>
<p>monthName : <span th:text="${#dates.monthName(itdragonDate)}"></span></p>
<p>year : <span th:text="${#dates.year(itdragonDate)}"></span></p>
<p>dayOfWeek : <span th:text="${#dates.dayOfWeek(itdragonDate)}"></span></p>
<p>dayOfWeekName : <span th:text="${#dates.dayOfWeekName(itdragonDate)}"></span></p>
<p>hour : <span th:text="${#dates.hour(itdragonDate)}"></span></p>
<p>minute : <span th:text="${#dates.minute(itdragonDate)}"></span></p>
<p>second : <span th:text="${#dates.second(itdragonDate)}"></span></p>
<p>createNow : <span th:text="${#dates.createNow()}"></span></p>
</div>
</body>
</html>
后臺負責給變量賦值,和跳轉頁面徐钠。
@RequestMapping("/tofunc")
public String toFunc(ModelMap map){
map.put("itdragonStr","itdragonBlog");
map.put("itdragonBool",true);
map.put("itdragonArray",new Integer[]{1,2,3,4});
map.put("itdragonList", Arrays.asList(1,3,2,4,0));
Map itdragonMap = new HashMap();
itdragonMap.put("thName","${#...}");
itdragonMap.put("desc","變量表達式內置方法");
map.put("itdragonMap",itdragonMap);
map.put("itdragonDate",new Date());
map.put("itdragonNum",888.888D);
return "admin/func";
}