Thymeleaf (麝香草葉子), /ˈtaɪmˌlɪːf/ 是一個服務端java模板引擎框架,它可以處理多種數據格式,包括HTML, XML, JavaScript, CSS以及普通文本。css
<!DOCTYPE html> <!--聲明 th 名稱空間--> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Good Thymes Virtual Grocery</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" type="text/css" media="all" href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" /> </head> <body> <!-- 引用文本--> <p th:text="#{home.welcome}">Welcome to our grocery store!</p> </body> </html>
Thymeleaf使用th:*
給現有HTML標籤增長屬性,所以直接打開模板也能預覽效果,很方便 。使用時首先須要像在jsp中同樣,在html
標籤內聲明th名稱空間,而後就可使用了。html
${...}
*{...}
#{...}
@{...}
~{...}
該表達書主要爲了實現i18n國際化,須要將多語言的文本放在/WEB-INF/templates
目錄下,以下java
/WEB-INF/templates/home_en.properties
英文的翻譯./WEB-INF/templates/home.properties
默認的文本<!--經常使用使用方法--> <p th:text="#{home.welcome}">Hello World</p> <!--unescaped text 不轉義文本--> <p th:utext="#{home.welcome}">
也能夠傳參給文本web
#home.properties文件 home.welcome=hello, {0}!
<!-- Thymeleaf解析後會將p標籤中的Welcome User!替換爲th:text指定的文本 --> <p th:text="#{home.welcome(${session.user.name})}"> Welcome User! </p> <!--消息的key也能夠經過動態去獲取 --> <p th:utext="#{${welcomeMsgKey}(${session.user.name})}"> Welcome User! </p>
Thymeleaf的 ${...}是OGNL (Object-Graph Navigation Language) expressions 語法格式,跟jsp中使用方法差很少,使用示例express
/* * Access to properties using the point (.). Equivalent to calling property getters. */ ${person.father.name} /* * Access to properties can also be made by using brackets ([]) and writing * the name of the property as a variable or between single quotes. */ ${person['father']['name']} /* * If the object is a map, both dot and bracket syntax will be equivalent to * executing a call on its get(...) method. */ ${countriesByCode.ES} ${personsByName['Stephen Zucchini'].age} /* * Indexed access to arrays or collections is also performed with brackets, * writing the index without quotes. */ ${personsArray[0].name} /* * Methods can be called, even with arguments. */ ${person.createCompleteName()} ${person.createCompleteNameWithSeparator('-')}
#ctx
: the context object.api
#vars:
the context variables.session
#locale
: the context locale.app
#request
: (only in Web Contexts) the HttpServletRequest
object.框架
#response
: (only in Web Contexts) the HttpServletResponse
object.less
#session
: (only in Web Contexts) the HttpSession
object.
#servletContext
: (only in Web Contexts) the ServletContext
object.
表達式工具對象
#execInfo
: information about the template being processed.#messages
: methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.#uris
: methods for escaping parts of URLs/URIs#conversions
: methods for executing the configured conversion service (if any).#dates
: methods for java.util.Date
objects: formatting, component extraction, etc.#calendars
: analogous to #dates
, but for java.util.Calendar
objects.#numbers
: methods for formatting numeric objects.#strings
: methods for String
objects: contains, startsWith, prepending/appending, etc.#objects
: methods for objects in general.#bools
: methods for boolean evaluation.#arrays
: methods for arrays.#lists
: methods for lists.#sets
: methods for sets.#maps
: methods for maps.#aggregates
: methods for creating aggregates on arrays or collections.#ids
: methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).<!--表達式工具對象的使用--> <p> Today is: <span th:text="${#calendars.format(today,'dd MMMM yyyy')}">13 May 2011</span> </p>
<div th:object="${session.user}"> <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p> <p>Surname: <span th:text="*{lastName}">Pepper</span>.</p> <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p> </div> <!-- 等價於 --> <div> <p>Name: <span th:text="${session.user.firstName}">Sebastian</span>.</p> <p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p> <p>Nationality: <span th:text="${session.user.nationality}">Saturn</span>.</p> </div> <!-- 還能夠混合使用--> <div th:object="${session.user}"> <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p> <p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p> <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p> </div> <!-- #object 引用表達式的對象 --> <div th:object="${session.user}"> <p>Name: <span th:text="${#object.firstName}">Sebastian</span>.</p> <p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p> <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p> </div>
th:object
定義選擇的對象,在標籤內使用*{...}
來取出對象中相應的數據,若是沒有選擇的對象直接使用*{...}
等價於#{...}
<!-- Will produce 'http://localhost:8080/gtvg/order/details?orderId=3' (plus rewriting) --> <a href="details.html" th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">view</a> <!-- Will produce '/gtvg/order/details?orderId=3' (plus rewriting) --> <a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a> <!-- Will produce '/gtvg/order/3/details' (plus rewriting) --> <a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>
<!-- 基本的使用--> <p> Now you are looking at a <span th:text="'working web application'">template file</span>. </p> <p>The year is <span th:text="2013">1492</span>.</p> <!-- ==false 須要寫在{}外面才交由thymeleaf處理,寫在裏面時交由 OGNL/SpringEL處理 --> <div th:if="${user.isAdmin()} == false"> </div> <div th:if="${user.isAdmin() == false}"></div> <!--判空--> <div th:if="${variable.something} == null"> <!-- 文本連接 --> <span th:text="'The name of the user is ' + ${user.name}"> <!-- 文本替換,(免去+號連接字符串),須要寫在 || 之間 僅變量,信息表達式可使用${...}, *{...}, #{...} --> <span th:text="|Welcome to our application, ${user.name}!|">
<!-- 也可使用文本 div (/), mod (%).--> <div th:with="isEven=(${prodStat.count} % 2 == 0)">
html起止標籤的緣故,大於,小於等須要使用轉義
gt
(>
), lt
(<
), ge
(>=
), le
(<=
), not
(!
) eq
(==
), neq
/ne
(!=
).
<div th:if="${prodStat.count} > 1"> <span th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')"
<!--C中的三元運算符 --> <tr th:class="${row.even}? 'even' : 'odd'"> </tr> <!-- 省略--> <tr th:class="${row.even}? 'alt'"> ... </tr>
<div th:object="${session.user}"> <p>Age: <span th:text="*{age}?: '(no age specified)'">27</span>.</p> </div> <!-- 等價於,省略表達式爲true時的語句 --> <p>Age: <span th:text="*{age != null}? *{age} : '(no age specified)'">27</span>.</p>
空操做符( No-Operation token)使用下劃線表示_
,它容許原生頁面定義的文本爲默認值,便於模板的設計
<span th:text="${user.name} ?: 'no user authenticated'">...</span> <span th:text="${user.name} ?: _">no user authenticated</span>
Thymeleaf 定義了雙花括號語法用於變量${...}
和選擇表達式*{...}
<td th:text="${{user.lastAccessDate}}">...</td>
<table> <tr> <th>NAME</th> <th>PRICE</th> <th>IN STOCK</th> </tr> <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> </table>
prod
保存每次遍歷的對象,iterStat
保存遍歷的相關信息
index
property. 遍歷索引,從0開始count
property. 遍歷計數,從1開始size
property. 被遍歷對象的大小current
property. 當前遍歷的對象even/odd
boolean properties. 奇偶布爾值first
boolean property. 是不是遍歷第一個last
boolean property. 是不是遍歷最後一個java.util.Iterable
java.util.Enumeration
.java.util.Iterator
, whose values will be used as they are returned by the iterator, without the need to cache all values in memory.java.util.Map
. When iterating maps, iter variables will be of class java.util.Map.Entry
.<!-- 若是if表達式成立則顯示該標籤--> <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:if="${not #lists.isEmpty(prod.comments)}">view</a> <!--還可使用相反的表達式unless --> <a href="comments.html" th:href="@{/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">view</a>
true
.(If value is null, th:if will evaluate to false).
<div th:switch="${user.role}"> <p th:case="'admin'">User is an administrator</p> <p th:case="#{roles.manager}">User is a manager</p> <p th:case="*">User is some other thing</p> <!--默認值--> </div>
使用th:fragment
定義須要複用的代碼片斷,th:insert
或th:replac
引用片斷
~{templatename::selector}
引用片斷
~{templatename}
引用整個文件
~{::selector}
或~{this::selector}
引用自身的代碼片斷
<!--定義代碼片斷 --> <html xmlns:th="http://www.thymeleaf.org"> <body> <div th:fragment="copy"> © 2011 The Good Thymes Virtual Grocery </div> </body> </html> <!-- 引用代碼片 --> <body> <div th:insert="footer :: copy"></div> </body> <!-- 根據條件引用--> <div th:insert="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div> <!-- 根據id引用 css選擇器語法相似--> <div id="copy-section"> © 2011 The Good Thymes Virtual Grocery </div> <div th:insert="~{footer :: #copy-section}"></div>
th:insert
, th:replace
,th:include
th:insert
is the simplest: it will simply insert the specified fragment as the body of its host tag. (在定義的標籤體內引用代碼片斷)
th:replace
actually replaces its host tag with the specified fragment.(將定義標籤替換爲引用的代碼片斷)
th:include
is similar to th:insert
, but instead of inserting the fragment it only inserts the contents of this fragment.(Thymeleaf 3.0後不推薦使用)
<!--定義參數化代碼片斷--> <div th:fragment="frag (onevar,twovar)"> <p th:text="${onevar} + ' - ' + ${twovar}">...</p> </div> <!--使用 使用參數名時順序不重要 --> <div th:replace="::frag (${value1},${value2})">...</div> <div th:replace="::frag (onevar=${value1},twovar=${value2})">...</div> <div th:replace="::frag (twovar=${value2},onevar=${value1})">...</div>
<!-- 使用th:with定義,能夠再標籤體中使用--> <div th:with="firstPer=${persons[0]}"> <p> The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>. </p> </div>
1.Thymleaf Document(http://www.thymeleaf.org/documentation.html)
2.屬性優先級(http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#attribute-precedence)
3.可用屬性(http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#setting-value-to-specific-attributes)