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官方的推薦使用模板。html

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

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

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

1.2 模板類型

容許您處理六種模板,有:spring

- HTML
- XML
- TEXT
- JAVASCRIPT
- CSS
- RAWexpress

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步:
一、先計算變量${sel.code},假如值是welcome
二、__的含義是須要預處理的變量值,那麼就變成#{home.welcome}
三、計算最終結果,簡單吧

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步
一、先計算變量${sel.code},假如值是welcome
二、__的含義是須要預處理的變量值,那麼就變成#{home.welcome}
三、計算最終結果,簡單吧

默認處理表達式 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>
相關文章
相關標籤/搜索