本篇文章將以SpringBoot爲框架來介紹Thymeleaf的用法。javascript
1 資源文件的約定目錄結構 css
Maven的資源文件目錄:/src/java/resources
spring-boot項目靜態文件目錄:/src/java/resources/static
spring-boot項目模板文件目錄:/src/java/resources/templates
spring-boot靜態首頁的支持,即index.html放在如下目錄結構會直接映射到應用的根目錄下:html
classpath:/META-INF/resources/index.html
classpath:/resources/index.html
classpath:/static/index.html
calsspath:/public/index.html 前端
所以,SpringBoot默認的靜態資源文件應該放在resources/tatic下,而靜態頁面應該放在resources/templates文件夾下,這兩個文件不會自動建立,須要手動建立,以下圖所示:java
2 Maven依賴:jquery
1 <!-- thymeleaf 前端渲染模板依賴 --> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-thymeleaf</artifactId> 5 <version>2.0.0.RELEASE</version> 6 </dependency>
3 html頁面中(<html>標籤處):web
1 <html xmlns="http://www.w3.org/1999/xhtml" 2 xmlns:th="http://www.thymeleaf.org" 3 xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
4 application.properties配置(application.yml則根據格式相應變化便可):spring
1 # THYMELEAF (ThymeleafAutoConfiguration) 2 #開啓模板緩存(默認值:true) 3 spring.thymeleaf.cache=true 4 #Check that the template exists before rendering it. 5 spring.thymeleaf.check-template=true 6 #檢查模板位置是否正確(默認值:true) 7 spring.thymeleaf.check-template-location=true 8 #Content-Type的值(默認值:text/html) 9 spring.thymeleaf.content-type=text/html 10 #開啓MVC Thymeleaf視圖解析(默認值:true) 11 spring.thymeleaf.enabled=true 12 #模板編碼 13 spring.thymeleaf.encoding=UTF-8 14 #要被排除在解析以外的視圖名稱列表,用逗號分隔 15 spring.thymeleaf.excluded-view-names= 16 #要運用於模板之上的模板模式。另見StandardTemplate-ModeHandlers(默認值:HTML5) 17 spring.thymeleaf.mode=HTML5 18 #在構建URL時添加到視圖名稱前的前綴(默認值:classpath:/templates/) 19 spring.thymeleaf.prefix=classpath:/templates/ 20 #在構建URL時添加到視圖名稱後的後綴(默認值:.html) 21 spring.thymeleaf.suffix=.html 22 #Thymeleaf模板解析器在解析器鏈中的順序。默認狀況下,它排第一位。順序從1開始,只有在定義了額外的TemplateResolver Bean時才須要設置這個屬性。 23 spring.thymeleaf.template-resolver-order= 24 #可解析的視圖名稱列表,用逗號分隔 25 spring.thymeleaf.view-names=
配置好以上的代碼,此時在html模板文件中動態的屬性使用th:命名空間修飾,就可使用Thymeleaf了。express
1 引用靜態資源文件:數組
好比CSS和JS文件,語法格式爲「@{}」,如@{/js/blog/blog.js}會引入/static目錄下的/js/blog/blog.js文件。
2 訪問spring-mvc中model的屬性:
語法格式爲「${}」,如${user.id}能夠獲取model裏的user對象的id屬性,相似JSTL。
3 循環:
在html的標籤中,加入th:each=「value:${list}」形式的屬性,如<span th:each=」user:${users}」></span>能夠迭代users的數據
4 判斷:
在html標籤中,加入th:if=」表達式」能夠根據條件顯示html元素
1 <span th:if="${not #lists.isEmpty(blog.publishTime)}"> 2 <span id="publishtime" th:text="${#dates.format(blog.publishTime, 'yyyy-MM-dd HH:mm:ss')}"></span> 3 </span>
以上代碼表示若blog.publishTime時間不爲空,則顯示時間。
5 時間格式化:
1 ${#dates.format(blog.publishTime,'yyyy-MM-dd HH:mm:ss')} //表示將時間格式化爲」yyyy-MM-dd HH:mm:ss」格式化寫法與Java格式化Date的寫法是一致的。
6 字符串拼接:
有兩種形式 ,好比拼接這樣一個URL:/blog/delete/{blogId}
第一種:th:href="'/blog/delete/' + ${blog.id }"
第二種:th:href="${'/blog/delete/' + blog.id }"
7 爲CSS樣式的某些路徑使用thyemleaf表達式:
1 <div th:style="'background:url(' + @{/<path-to-image>} + ');'"></div>
8 使用th:utext="@{}" 可讓變量裏面的html標籤被解析
1 簡單表達式 (simple expressions)
1 ${...} 變量表達式 2 3 *{...} 選擇變量表達式 4 5 #{...} 消息表達式 6 7 @{...} 連接url表達式
2 字面量
1 'one text','another one!',... 文本 2 3 0,34,3.0,12.3,... 數值 4 5 true false 布爾類型 6 7 null 空 8 9 one,sometext,main 文本字符
3 文本操做
1 + 字符串鏈接 2 3 |The name is ${name}| 字符串鏈接
4 算術運算
1 + , - , * , / , % 二元運算符 2 3 - 負號(一元運算符)
5 布爾操做
1 and,or 二元操做符 2 3 !,not 非(一元操做符)
6 關係操做符
1 > , < , >= , <= (gt , lt , ge , le) 2 3 == , != (eq, ne)
7 條件判斷
1 (if) ? (then) if-then 2 3 (if) ? (then) : (else) if-then-else 4 5 <tr th:class="${row.even}? 'even' : 'odd'"> 6 ... 7 </tr>
條件表達式中的三個部分自身也能夠是表達式,也能夠是變量(${...}, *{...}), 消息(#{...}), URL (@{...}) 或字面量 ('...')
條件表達式也可使用括號來嵌套:
1 <tr th:class="${row.even}? (${row.first}? 'first' : 'even') : 'odd'"> 2 ... 3 </tr>
else表達式也能夠省略,當條件爲false時,會返回null:
1 <tr th:class="${row.even}? 'alt'"> 2 ... 3 </tr> 4 (value) ?: (defaultvalue) Default
只有在第一個表達式返回null時,第二個表達式纔會運算
8 表達式工具對象
1 #dates 與java.util.Date對象的方法對應,格式化、日期組件抽取等等 2 #calendars 相似#dates,與java.util.Calendar對象對應 3 #numbers 格式化數字對象的工具方法 4 #strings 與java.lang.String對應的工具方法:contains、startsWith、prepending/appending等等 5 #objects 用於對象的工具方法 6 #bools 用於布爾運算的工具方法 7 #arrays 用於數組的工具方法 8 #lists 用於列表的工具方法 9 #sets 用於set的工具方法 10 #maps 用於map的工具方法 11 #aggregates 用於建立數組或集合的聚合的工具方法 12 #messages 用於在變量表達式內部獲取外化消息的工具方法,與#{…}語法獲取的方式相同 13 #ids 用於處理可能重複出現(例如,做爲遍歷的結果)的id屬性的工具方法
9 連接URL
URL在web模板中是一級重要元素,使用@{…}表示
URL的類型:
絕對URL:
http://www.thymeleaf.org
相對URL:
1 頁面相對: user/login.html 2 上下文相對:/itemdetails?id=3 (服務器上下文名稱會被自動添加) 3 服務器相對:~/billing/processInvoice(容許調用同一服務器上的另外一個上下文中的URL) 4 協議相對://code.jquery.com/jquery-2.0.3.min.js
Thymeleaf在任何狀況下均可以處理絕對URL,對於相對URL,則須要使用一個實現了IWebContext接口的上下文對象,這個對象包含了來自HTTP請求的信息,這些信息用於建立相對連接。
1 <!-- Will produce 'http://localhost:8080/gtvg/order/details?orderId=3' (plus rewriting) --> 2 <a href="details.html" th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">view</a> 3 4 <!-- Will produce '/gtvg/order/details?orderId=3' (plus rewriting) --> 5 <a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a> 6 7 <!-- Will produce '/gtvg/order/3/details' (plus rewriting) --> 8 <a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>
10 預處理
Thymeleaf提供預處理表達式的功能。
它是在錶殼式正常執行前執行的操做,容許修改最終將要被執行的表達式。
預處理表達式跟正常的同樣,但被兩個下劃線包圍住,例如:__${expression}__
假設有一個i18n消息文件Message_fr.properties,裏面有一個條目包含了一個調用具體語言的靜態方法的OGNL表達式:
article.text=@myapp.translator.Translator@translateToFrench({0})
Messages_es.properties中的等價條目:
article.text=@myapp.translator.Translator@translateToSpanish({0})
能夠根據locale先建立用於運算表達式的標記片斷,本例中,先經過預處理選擇表達式,而後讓Thymeleaf處理這個選擇出來的表達式:
<p th:text="${__#{article.text('textVar')}__}">Some text here...</p>
對於locale爲French的狀況,上面的表達式通過預處理後,得出的等價物以下:
<p th:text="${@myapp.translator.Translator@translateToFrench(textVar)}">Some text here...</p>
1 th:attr 任何屬性值
1 <form action="subscribe.html" th:attr="action=@{/subscribe}"> 2 <fieldset> 3 <input type="text" name="email" /> 4 <input type="submit" value="Subscribe me!" th:attr="value=#{subscribe.submit}"/> 5 </fieldset> 6 </form>
多個屬性一塊兒設置,用逗號隔開
<img src="../../images/gtvglogo.png" th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />
2 設置指定屬性
th:abbr
th:accept
th:accept-charset
th:accesskey
th:action
th:align
th:alt
th:archive
th:audio
th:autocomplete
th:axis
th:background
th:bgcolor
th:border
th:cellpadding
th:cellspacing
th:challenge
th:charset
th:cite
th:class
th:classid ...
1 <input type="submit" value="Subscribe me!" th:value="#{subscribe.submit}"/> 2 <form action="subscribe.html" th:action="@{/subscribe}"> 3 <li><a href="product/list.html" th:href="@{/product/list}">Product List</a></li>
設置多個屬性在同一時間 有兩個特殊的屬性能夠這樣設置: th:alt-title 和 th:lang-xmllang
th:alt-title 設置 alt 和 title
th:lang-xmllang 設置 lang 和 xml:lang
1 <img src="../../images/gtvglogo.png" th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" /> 2 3 <img src="../../images/gtvglogo.png"th:src="@{/images/gtvglogo.png}" th:title="#{logo}" th:alt="#{logo}" /> 4 5 <img src="../../images/gtvglogo.png"th:src="@{/images/gtvglogo.png}" th:alt-title="#{logo}" />
前置和後置添加屬性值 th:attrappend 和 th:attrprepend
<input type="button" value="Do it!" class="btn" th:attrappend="class=${' ' + cssStyle}" />
編譯後:
<input type="button" value="Do it!" class="btn warning" />
還有兩個特定的添加屬性 th:classappend 和 th:styleappend
<tr th:each="prod : ${prods}" class="row" th:classappend="${prodStat.odd}? 'odd'">
3 修復的布爾屬性
<input type="checkbox" name="active" th:checked="${user.active}" />
全部修復的布爾屬性:
th:async
th:autofocus
th:autoplay
th:checked
th:controls
th:declare
th:default
th:defer
th:disabled
th:formnovalidate
th:hidden
th:ismap
th:loop
th:multiple
th:novalidate
th:nowrap
th:open
th:pubdate
th:readonly
th:required
th:reversed
th:scoped
th:seamless
th:selected
HTML5友好的屬性及元素名
1 <table> 2 <tr data-th-each="user : ${users}"> 3 <td data-th-text="${user.login}">...</td> 4 <td data-th-text="${user.name}">...</td> 5 </tr> 6 </table>
注:data-{prefix}-{name}是編寫HTML5自定義屬性的標準語法,不須要開發者使用th:*這樣的命名空間,Thymeleaf讓這種語法自動對全部dialect均可用。
1 基礎
1 <tr th:each="prod : ${prods}"> 2 <td th:text="${prod.name}">Onions</td> 3 <td th:text="${prod.price}">2.41</td> 4 <td th:text="${prod.inStock}? #{true} : #{false}">yes</td> 5 </tr>
可遍歷的對象:實現java.util.Iterable、java.util.Map(遍歷時取java.util.Map.Entry)、array、任何對象都被看成只有對象自身一個元素的列表
2 狀態
當前遍歷索引,從0開始,index屬性
當前遍歷索引,從1開始,count屬性
總元素數量,size屬性
每一次遍歷的iter變量,current屬性
當前遍歷是even仍是odd,even/odd布爾屬性
當前遍歷是第一個,first布爾屬性
當前遍歷是最後一個,last布爾屬性
1 <tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'"> 2 <td th:text="${prod.name}">Onions</td> 3 <td th:text="${prod.price}">2.41</td> 4 <td th:text="${prod.inStock}? #{true} : #{false}">yes</td> 5 </tr>
若不指定狀態變量,Thymeleaf會默認生成一個名爲「變量名Stat」的狀態變量:
1 <tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'"> 2 <td th:text="${prod.name}">Onions</td> 3 <td th:text="${prod.price}">2.41</td> 4 <td th:text="${prod.inStock}? #{true} : #{false}">yes</td> 5 </tr>
1 <tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'"> 2 <td th:text="${prod.name}">Onions</td> 3 <td th:text="${prod.price}">2.41</td> 4 <td th:text="${prod.inStock}? #{true} : #{false}">yes</td> 5 <td> 6 <span th:text="${#lists.size(prod.comments)}">2</span> comment/s 7 <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:if="${not #lists.isEmpty(prod.comments)}">view</a> 8 </td> 9 </tr>
<a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:if="${not #lists.isEmpty(prod.comments)}">view</a>
th:if 不僅運算布爾條件,它對如下狀況也運算爲true:
值不爲null
值爲boolean且爲true
值爲數字且非0
值爲字符且非0
值是字符串且不是:「false」,「off」,「no」
值不是boolean、數字、字符、字符串
若是值爲null,則th:if運算結果爲false
th:if的反面是th:unless
1 <a href="comments.html" th:href="@{/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">view</a> 2 th:switch 和 th:case 3 4 <div th:switch="${user.role}"> 5 <p th:case="'admin'">User is an administrator</p> 6 <p th:case="#{roles.manager}">User is a manager</p> 7 </div> 8 9 <div th:switch="${user.role}"> 10 <p th:case="'admin'">User is an administrator</p> 11 <p th:case="#{roles.manager}">User is a manager</p> 12 <p th:case="*">User is some other thing</p> 13 </div>
總結一下在使用過程當中遇到的坑:
1 獲取項目根目錄,不少時候咱們都須要獲取本項目的根目錄,可是使用的代碼是如下代碼才能得到:
<script th:inline="javascript" type="text/javascript"> var ctx=[[${#httpServletRequest.getContextPath()}]]; </script>
注意以上代碼,若是須要在自定義的javascript中使用thymeleaf表達式,則須要將script聲明一下:th:inline="javascript"。
2 獲取圖片路徑,當咱們使用thymeleaf的時候必定要注意單、雙引號的區別,否則是沒法獲取到對應的值或者路徑的:
<span class="img" th:style="'background-image: url('+@{/images/news/}+${top4News[2].originArticleId}+'/1.jpg'+');'"></span>
請注意以上代碼:當咱們要在backgroud-image這個標籤下引用對應路徑的img時:
首先使用th:style進行修飾。
而後在background-image標籤先後必定要加單引號,不然不會起做用:
'background-image:xxx'
接着就是在url裏面拼接你的img路徑,請注意url('xxx'),也有單引號!
最後才能經過此路徑獲取到相應的圖片。
在使用thymeleaf的過程當中,遇到了一些坑,但願你們在這樣的坑中少走一些彎路。