Thymeleaf語法

官方文檔(基于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:textth: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 : 聲明變量捎拯,一般和*{}一起配合使用泪幌,達到偷懶的效果。

  1. 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>

項目結構:


捕獲.PNG
<!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>
捕獲.PNG

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">
    &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>
    &copy; 2011 The Good Thymes Virtual Grocery
    </footer>
</div>
<!--th:replace是將代碼塊代替當前div,其html結構和之前一致-->
<footer>
&copy; 2011 The Good Thymes Virtual Grocery
</footer>
<!--th:include是將代碼塊footer的內容插入到div中谷遂,即少了一層footer-->
<div>
&copy; 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";
    }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末癌刽,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子尝丐,更是在濱河造成了極大的恐慌显拜,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摊崭,死亡現場離奇詭異讼油,居然都是意外死亡,警方通過查閱死者的電腦和手機呢簸,發(fā)現死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門矮台,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乏屯,“玉大人,你說我怎么就攤上這事瘦赫〕皆危” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵确虱,是天一觀的道長含友。 經常有香客問我,道長校辩,這世上最難降的妖魔是什么窘问? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮宜咒,結果婚禮上惠赫,老公的妹妹穿的比我還像新娘。我一直安慰自己故黑,他們只是感情好儿咱,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著场晶,像睡著了一般混埠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诗轻,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天钳宪,我揣著相機與錄音,去河邊找鬼扳炬。 笑死使套,一個胖子當著我的面吹牛,可吹牛的內容都是我干的鞠柄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嫉柴,長吁一口氣:“原來是場噩夢啊……” “哼厌杜!你這毒婦竟也來了?” 一聲冷哼從身側響起计螺,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤夯尽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后登馒,有當地人在樹林里發(fā)現了一具尸體匙握,經...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年陈轿,在試婚紗的時候發(fā)現自己被綠了圈纺。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秦忿。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蛾娶,靈堂內的尸體忽然破棺而出灯谣,到底是詐尸還是另有隱情,我是刑警寧澤蛔琅,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布胎许,位于F島的核電站,受9級特大地震影響罗售,放射性物質發(fā)生泄漏辜窑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一寨躁、第九天 我趴在偏房一處隱蔽的房頂上張望穆碎。 院中可真熱鬧,春花似錦朽缎、人聲如沸惨远。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽北秽。三九已至,卻和暖如春最筒,著一層夾襖步出監(jiān)牢的瞬間贺氓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工床蜘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留辙培,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓邢锯,卻偏偏與公主長得像扬蕊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子丹擎,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內容