Thymeleaf教程入門到深入1:基礎介紹


1 介紹

1.1 簡介

  Thymeleaf是一個用於Web和獨立Java環境的模板引擎,能夠處理HTML、XML、JavaScript、CSS甚至純文本。能輕易的與Spring MVC等Web框架進行集成作為Web應用的模板引擎。與其它模板引擎(比如FreeMaker)相比,Thymeleaf最大的特點是能夠直接在瀏覽器中打開並正確顯示模板頁面,而不需要啟動整個Web應用(更加方便前后端分離,比如方便類似VUE前端設計頁面),拋棄JSP吧。
  Thymeleaf 3.0是一個完全徹底重構的模板引擎(官網原文:Thymeleaf 3.0 builds around a completely new template processing engine),極大的減少內存占用和提升性能和並發性,避免v2.1版因大量的輸出標記的集合產生的資源占用。
  Thymeleaf 3.0放棄了大多數面向DOM的處理機制,變成了一個基於事件的模板處理器,它通過處理模板標記或文本並立即生成其輸出,甚至在新事件之前響應模板解析器/緩存事件。Thymeleaf是Spring Boot官方的推薦使用模板。

3.0版的模型解析事件模型:

2.1的性能和Velocity、Freemarker原先十幾倍的差距,到了2015年的3.0版時已經在顯著縮小,但目前性能還是和主流引擎有差距,見:

https://github.com/jreijn/spring-comparing-template-engines/issues/19

1.2 模板類型

允許您處理六種模板,有:

- HTML
- XML
- TEXT
- JAVASCRIPT
- CSS
- RAW

2 標准表達式語法


2.1 簡單表達式

  • 變量表達式: ${...}
  • 選擇變量表達式: *{...}
  • 消息表達式: #{...}
  • URL 表達式: @{...}
  • 代碼段表達式: ~{...}

變量表達式 Variable expressions: ${...}

變量表達式在Spring中就是模型屬性

例如:${user.name}
定義在屬性中:<span th:text="${book.author.name}">
遍歷:<li th:each="book : ${books}">

<!-- springmvc 保存了一個 model 對象: departments -->

<!-- 獲取所有 departments -->
<p th:text="${departments}"></p>
<!-- 獲取 departments 的第一個元素 -->
<p th:text="${departments[0]}"></p>
<!-- 獲取第一個 department 對象的 name 屬性 -->
<p th:text="${departments[0].name}"></p>
<!-- 也可以用 ['name'] 來獲取第一個 department 對象的 name 屬性 -->
<p th:text="${departments[0]['name']}"></p>
<!-- 甚至可以調用方法! -->
<p th:text="${departments[0].getId()}"></p>
<p th:text="${departments[0]['name'].substring(0, 1)}"></p>

 

選擇變量表達式 Selection expressions: *{...}

選擇表達式就像變量表達式,它們用於先前選擇的對象上執行,而不是在整個上下文變量映射中執行。
只要是沒有選擇的對象,選擇表達式與變量表達式的語法是完全一樣的。那什么是選擇的對象呢?是一個:th:object對象屬性綁定的對象。

例如:*{customer.name}
展示book變量的屬性:

<div th:object="${book}">
<span th:text="*{title}">...</span>
</div>
<div th:object="document[2]">
<!-- 以下三種方式在這種情況下是等價的 -->
<p th:text="${#object.id}"></p>
<p th:text="*{id}"></p>
<p th:text="${document[2].id}"></p>
</div>

消息表達式 Message expressions: #{...}

消息表達式用於展示靜態資源的內容,比如i18n屬性配置文件

例如:#{main.title}
一個完整的例子:

<table>
...
<th th:text="#{header.address.city}">...</th>
<th th:text="#{header.address.country}">...</th>
...
</table>
<!-- 還可以結合變量表達式使用  -->
#{${config.welcomeKey}}

比如新建/WEB-INF/templates/home.properties,home.welcome的內容:home.welcome=this messages is from home.properties!
使用消息表達式:<p th: text=" #{home.welcome}" >This text will not be show! </p>

一個更深入的例子:

結合消息表達式、變量表達式、預處理表達式

#{home.__${sel.code}__}


看上去很亂是吧,實際上可以分解成3步:
1、先計算變量${sel.code},假如值是welcome
2、__的含義是需要預處理的變量值,那么就變成#{home.welcome}
3、計算最終結果,簡單吧

URL 表達式 Link (URL) expressions: @{...}

例如:<a th:href="@{/order/list}">...</a>
帶參數的URL:<a th:href="@{/order/details(id=${orderId},type=${orderType})}">...</a>
相對地址:<a th:href="@{../documents/report}">...</a>
絕對地址:<a th:href="@{http://www.mycompany.com/main}">...</a>

代碼段表達式 Fragment expressions: ~{...}

用於整段內容的引用。
例如:<div th:insert="~{commons :: main}">...</div>

整體的例子:

<div th:with="frag=~{footer :: #main/text()}">
<p th:insert="${frag}">
</div>

詳細介紹:https://github.com/thymeleaf/thymeleaf/issues/451


2.2 文字和操作

  • 文本字面量: 'some text'
  • 數值字面量: 0, 34, 3.0, 12.3
  • 布爾值字面量: true, false
  • Null 值字面量: null
  • Tokens 字面量: one, content, sometext, ...

文本操作符

  • 字符串連接: +

比如附加字符:<span th:text="'The name of the user is ' + ${user.name}">

  • 字面量替換: |The name is ${name}|

字面量替換主要用於連接字符,比如<span th:text="|The name of the user is ${user.name}|">就和上面的一樣

算術操作符

  • 二元操作符: +, -, *, /, %
  • 負數(一元操作符): -

布爾操作符(邏輯操作符)

  • 二元操作符: and, or
  • 非(一元操作符): !, not

比較操作符

  • 比較: >, <, >=, <= (gt, lt, ge, le)
  • 相等性: ==, != (eq, ne)

條件操作符

  • if-then: (if) ? (then)
  • if-then-else: '(if) ? (then) : (else)'
  • 默認: (value) ?: (defaultvalue)

2.3 特殊符號

忽略操作 No-Operation token: _

例子:<div id="main" th:text="${data.hasId()} ? ${data.value} : _">...</div>

如變量${data.hasId()} == true ,則輸出類似:<div id="main" text="模型的value值">...</div>
如變量${data.hasId()} == false ,則輸出類似:<div id="main">...</div>

解耦模板邏輯 Decoupled Template Logic

見:https://github.com/thymeleaf/thymeleaf/issues/465

轉義

比如<p th:text="'man, <br>Let\'s</br> fish!'"></p>
因為Let's包含 ' , 得用 \ 進行轉義
輸出:man, <br>Let's</br> fish!

非轉義文本 Unescaped Text

假如配置文件為:home.welcome=Welcome to our <b>fantastic</b> grocery store!
直接使用會造成問題,輸出:<p>Welcome to our &lt;b&gt;fantastic&lt;/b&gt; grocery store!</p>
使用th:utext可以解決問題,如:
<p th:utext="#{home.welcome}"></p>

輸出就是fantastic加粗體的文本:<p>Welcome to our <b>fantastic</b> grocery store!</p>
記得非轉義文本用th:utext,不要用th:text哦

預處理表達式

#{home.__${sel.code}__}

看上去很亂是吧,實際上可以分解成3步
1、先計算變量${sel.code},假如值是welcome
2、__的含義是需要預處理的變量值,那么就變成#{home.welcome}
3、計算最終結果,簡單吧

默認處理表達式 Default expressions (Elvis operator)

如果變量為空或者不滿足then條件,就用默認值,如:

<p>Age: <span th:text="*{age}?: '(no age specified)'">27</span>.</p>

等同:

<p>Age: <span th:text="*{age != null}? *{age} : '(no age specified)'">27</span>.</p>

 

3 數據遍歷

使用th:each屬性

<tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>

其中iterStat用於定義遍歷的狀態,比如是奇數還是偶數(iterStat.odd是奇)iterStat.even是偶數。
還有其他的屬性:

  • index :當前迭代索引,從0開始。這是索引屬性。
  • count :當前迭代索引,從1開始。這是計數屬性。
  • size :迭代變量中的元素總數。這是尺寸的屬性。
  • current :iter變量用於每次迭代。這是當前屬性。
  • even/odd :當前迭代是偶數還是奇數。這些是偶/奇布爾性質。
  • first :當前迭代是否是第一次迭代。這是第一個布爾屬性。
  • last :當前迭代是否為最后一次迭代。這是最后一個布爾屬性。

條件if表達式

<table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
<th>COMMENTS</th>
</tr>
<tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
<td>
<span th:text="${#lists.size(prod.comments)}">2</span> comment/s
<a href="comments.html" 
th:href="@{/product/comments(prodId=${prod.id})}" 
th:if="${not #lists.isEmpty(prod.comments)}">view</a>
</td>
</tr>
</table>

 

使用th:switch替代if

<div th:switch="${user.role}">
<p th:case="'admin'">User is an administrator</p>
<p th:case="#{roles.manager}">User is a manager</p>
</div>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM