Thymeleaf標準方言

本節將帶您瞭解一些最重要的概念,以瞭解以標準或SpringStandard方言編寫的Thymeleaf模板。

1. 什麼是標準方言?

Thymeleaf是非常非常可擴展的,它允許自定義的名字來定義一組模板屬性(或者甚至是標籤),用自定語法評估計算表達式和應用邏輯。它更像是一個模板引擎框架。

它還帶有一些稱爲標準方言(稱爲StandardSpringStandard)的東西,它們定義了一組功能,這些功能應該足以滿足大多數情況。可以識別這些標準方言在模板中的使用,因爲它將包含以th前綴開頭的屬性,如<span th:text="...">

請注意,StandardSpringStandard方言幾乎完全相同,只是SpringStandard包含了集成到Spring MVC應用程序中的特定功能(例如,使用Spring表達式語言進行表達式評估而不是OGNL)。

2. 標準表達式語法

大多數Thymeleaf屬性允許將它們的值設置爲或包含表達式,由於它們使用的方言,我們將其稱爲標準表達式。這些表達式可以有五種類型:

  • ${...} : 變量表達式。
  • *{...} : 選擇表達式。
  • #{...} : 消息 (i18n) 表達式。
  • @{...} : 鏈接 (URL) 表達式。
  • ~{...} : 片段表達式。

2.1 變量表達式

變量表達式是OGNL表達式 - 如果將ThymeleafSpring - 集成在上下文變量上(也稱爲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中使用循環將其評估爲迭代器。

2.2 選擇表達式

選擇表達式就像變量表達式一樣,它們不是整個上下文變量映射上執行,而是在先前選擇的對象。 它們看起來像這樣:

*{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());
}

2.3 消息(i18n)表達式

消息表達式(通常稱爲文本外部化,國際化或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})}

2.4 鏈接(URL)表達式

鏈接表達式在構建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重寫。

2.5 片段表達式

片段表達式是一種簡單的方法用來表示標記的片段並將其移動到模板中。 由於這些表達式,片段可以被複制,傳遞給其他模板的參數等等。

最常見的是使用th:insertth:replace來插入片段:

<div th:insert="~{commons :: main}">...</div>

但是它們可以在任何地方使用,就像任何其他變量一樣:

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

片段表達式可以有參數。

2.6 文字和操作

有很多類型的文字和操作可用,它們分別如下:

  • 文字

    • 文本文字,例如:'one text', 'Another one!',
    • 數字文字,例如:0,10, 314, 31.01, 112.83,
    • 布爾文字,例如:true,false
    • Null文字,例如:Null
    • 文字標記,例如:one, sometext, main,
  • 文本操作:

    • 字符串連接:+
    • 文字替換:|The name is ${name}|
  • 算術運算:

    • 二進制操作:+, -, *, /, %
    • 減號(一元運算符):-
  • 布爾運算:

    • 二進制運算符,and,or
    • 布爾否定(一元運算符):!,not
  • 比較和相等:

    • 比較運算符:>,<,>=,<=(gt,lt,ge,le)
    • 相等運算符:==, != (eq, ne)
  • 條件操作符:

    • If-then:(if) ? (then)
    • If-then-else:(if) ? (then) : (else)
    • Default: (value) ?: (defaultvalue)

2.7 表達式預處理

關於表達式的最後一件事是知道表達式預處理,在__之間指定,如下所示:

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

上面代碼中,第一個被執行的變量表達式是:${sel.code},並且將使用它的結果作爲表達式的一部分(假設${sel.code}的結果爲:ALL),在此處執行國際化的情況下(這將查找與關鍵selection.ALL消息)。

3. 基本的屬性

下面來看看標準方言中的幾個最基本的屬性。 從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}">