本節將帶您了解一些最重要的概念,以了解以標準或SpringStandard方言編寫的Thymeleaf模板。
Thymeleaf是非常非常可延伸的,它允許自定義的名字來定義一組模板屬性(或者甚至是標籤),用自定語法評估計算表示式和應用邏輯。它更像是一個模板引擎框架。
它還帶有一些稱為標準方言(稱為Standard和SpringStandard)的東西,它們定義了一組功能,這些功能應該足以滿足大多數情況。可以識別這些標準方言在模板中的使用,因為它將包含以th
字首開頭的屬性,如<span th:text="...">
。
請注意,Standard和SpringStandard方言幾乎完全相同,只是SpringStandard包含了整合到Spring MVC應用程式中的特定功能(例如,使用Spring表示式語言進行表示式評估而不是OGNL)。
大多數Thymeleaf屬性允許將它們的值設定為或包含表示式,由於它們使用的方言,我們將其稱為標準表示式。這些表示式可以有五種型別:
${...}
: 變數表示式。*{...}
: 選擇表示式。#{...}
: 訊息 (i18n) 表示式。@{...}
: 連結 (URL) 表示式。~{...}
: 片段表示式。變數表示式是OGNL表示式 - 如果將Thymeleaf 與Spring - 整合在上下文變數上(也稱為Spring術語中的模型屬性),則為Spring EL。 它們看起來像這樣:
${session.user.name}
它們作為屬性值或作為它們的一部分,取決於屬性:
<span th:text="${book.author.name}">
上面的表示式與下面是相同的(在OGNL和SpringEL中):
((Book)context.getVariable("book")).getAuthor().getName()
但是不僅在涉及輸出的場景中找到變數表示式,而且還可以使用更複雜的處理方式,如:條件,迭代…等等。
<li th:each="book : ${books}">
這裡${books}
從上下文中選擇名為books
的變數,並在th:each
中使用迴圈將其評估為疊代器。
選擇表示式就像變數表示式一樣,它們不是整個上下文變數對映上執行,而是在先前選擇的物件。 它們看起來像這樣:
*{customer.name}
它們所作用的物件由th:object
屬性指定:
<div th:object="${book}">
...
<span th:text="*{title}">...</span>
...
</div>
所以這相當於:
{
// th:object="${book}"
final Book selection = (Book) context.getVariable("book");
// th:text="*{title}"
output(selection.getTitle());
}
訊息表示式(通常稱為文字外部化,國際化或i18n)允許從外部源(如:.properties
)檔案中檢索特定於語言環境的訊息,通過鍵來參照這參照訊息。
在Spring應用程式中,它將自動與Spring的MessageSource機制整合。如下 -
#{main.title}
#{message.entrycreated(${entryId})}
以下是在模板中使用它們的方式:
<table>
...
<th th:text="#{header.address.city}">...</th>
<th th:text="#{header.address.country}">...</th>
...
</table>
請注意,如果希望訊息鍵由上下文變數的值確定,或者希望將變數指定為引數,則可以在訊息表示式中使用變數表示式:
#{${config.adminWelcomeKey}(${session.user.name})}
連結表示式在構建URL並向其新增有用的上下文和對談資訊(通常稱為URL重寫的過程)。
因此,對於部署在Web伺服器的/myapp
上下文中的Web應用程式,可以使用以下表示式:
<a th:href="@{/order/list}">...</a>
可以轉換成如下的東西:
<a href="/myapp/order/list">...</a>
甚至,如果需要保持對談,並且cookie未啟用(或者伺服器還不知道),那麼生成的格式為:
<a href="/myapp/order/list;jsessionid=s2ds3fa31abd241e2a01932">...</a>
網址也可以帶引數,如下所示:
<a th:href="@{/order/details(id=${orderId},type=${orderType})}">...</a>
這將產生類似以下的結果 -
<!-- 注意&符號會在標籤屬性中進行HTML跳脫... -->
<a href="/myapp/order/details?id=23&type=online">...</a>
連結表示式可以是相對的,在這種情況下,應用程式上下文將不會被加到URL的前面:
<a th:href="@{../documents/report}">...</a>
也是伺服器相對的(同樣,沒有應用程式上下文的字首):
<a th:href="@{~/contents/main}">...</a>
和協定相關(就像絕對URL一樣,但瀏覽器將使用與正在顯示的頁面相同的HTTP或HTTPS協定):
<a th:href="@{//static.mycompany.com/res/initial}">...</a>
當然,連結表示式也可以是絕對的:
<a th:href="@{http://www.mycompany.com/main}">...</a>
但是絕對(或協定相對)URL ,在Thymeleaf連結表示式中應該新增什麼值? 很簡單:由響應過濾器定義URL重寫:在基於Servlet的Web應用程式中,對於每個輸出的URL(上下文相對,相對,絕對…),在顯示URL之前,Thymeleaf總是呼叫HttpServletResponse.encodeUrl(...)
機制。 這意味著一個過濾器可以通過包裝HttpServletResponse物件來為應用程式執行自定義的URL重寫。
片段表示式是一種簡單的方法用來表示標記的片段並將其移動到模板中。 由於這些表示式,片段可以被複製,傳遞給其他模板的引數等等。
最常見的是使用th:insert
或th:replace
來插入片段:
<div th:insert="~{commons :: main}">...</div>
但是它們可以在任何地方使用,就像任何其他變數一樣:
<div th:with="frag=~{footer :: #main/text()}">
<p th:insert="${frag}">
</div>
片段表示式可以有引數。
有很多型別的文字和操作可用,它們分別如下:
文字
'one text'
, 'Another one!'
,…
0
,10
, 314
, 31.01
, 112.83
,…
true
,false
Null
one
, sometext
, main
,…
文字操作:
+
|The name is ${name}|
算術運算:
+
, -
, *
, /
, %
-
布林運算:
and
,or
!
,not
比較和相等:
>
,<
,>=
,<=
(gt
,lt
,ge
,le
)==
, !=
(eq
, ne
)條件操作符:
(if) ? (then)
(if) ? (then) : (else)
(value) ?: (defaultvalue)
關於表示式的最後一件事是知道表示式預處理,在__
之間指定,如下所示:
#{selection.__${sel.code}__}
上面程式碼中,第一個被執行的變數表示式是:${sel.code}
,並且將使用它的結果作為表示式的一部分(假設${sel.code}
的結果為:ALL
),在此處執行國際化的情況下(這將查詢與關鍵selection.ALL
訊息)。
下面來看看標準方言中的幾個最基本的屬性。 從th:
文字開始,它代替了標籤的主體:
<p th:text="#{msg.welcome}">Welcome everyone!</p>
現在,th:each
重複它所在元素的次數,由它的表示式返回的陣列或列表所指定的次數,為疊代元素建立一個內部變數,其語法與Java的foreach表示式相同:
<li th:each="book : ${books}" th:text="${book.title}">En las Orillas del Sar</li>
最後,Thymeleaf為特定的XHTML和HTML5屬性提供了許多th
屬性,這些屬性只評估它們的表示式,並將這些屬性的值設定為結果。
<form th:action="@{/createOrder}">
<input type="button" th:value="#{form.submit}" />
<a th:href="@{/admin/users}">