https://blog.csdn.net/weixin_45719444/article/details/122891930
介紹
官網:https://www.thymeleaf.org/
Thymeleaf是一個用於Web和獨立環境的現代伺服器端Java模板引擎。
簡單示例
開啟IDEA,建立一個maven工程(quickstart archetype)·。
在pom.xml檔案中匯入依賴,目前最新版本3.0.15:
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.15.RELEASE</version>
</dependency>
新建一個HelloWorld類,內容如下:
public static void main(String[] args) {
// 建立模板引擎
TemplateEngine engine = new TemplateEngine();
// 準備模板
String input = "<input type='text' th:value='helloWorld'/>";
// 準備資料
Context context = new Context();
// 呼叫引擎,處理模板和資料
String result = engine.process(input, context);
System.out.println("模板渲染結果==> " + result);
}
輸出結果:
這裡模板是HTML常見元件input框,type和value屬性。實際上模板引擎在解析模板時,透過‘th:’字首來鎖定要替換的值,就是這裡的‘helloWorld’內容。 但是這個資料是寫死的,下面我們將資料動態地呈現在頁面上。
使用模板資料
方便起見,我使用單元測試的方式來體驗thymeleaf的語法規則。
@Test
public void test1() {
// 建立模板引擎
TemplateEngine engine = new TemplateEngine();
// 準備模板
String input = "<input type='text' th:value='${name}'/>";
// 準備資料
Context context = new Context();
context.setVariable("name", "李四");
// 處理模板和資料
String result = engine.process(input, context);
System.out.println("模板渲染結果==> " + result);
}
${name} 相當於一個佔位符,透過我們傳遞的資料進行替換。
context.setVariable("name", "李四") ,此方法透過佔位符(唯一標識),動態設定資料。
輸出結果:
這樣我們可以提供不同資料,重複利用模板來得到不同結果。
使用模板檔案
在resources資料夾下建立html模板,內容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
template: <input type="text" th:value="${name}"/>
</div>
</body>
</html>
編寫測試方法:
@Test
public void test2() {
// 建立模板引擎
TemplateEngine engine = new TemplateEngine();
// 讀取模板檔案(在類路徑下找要渲染的模板)
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
// 設定引擎使用 resolver
engine.setTemplateResolver(resolver);
// 指定資料
Context context = new Context();
context.setVariable("name", "李四");
// 處理模板(注:檔名字尾不能省)
String result = engine.process("index.html", context);
System.out.println("模板檔案渲染結果==> " + result);
}
這個示例說明我們可以透過類路徑載入一個模板檔案,作為真正的模板,再結合設定的資料將最終結果輸出。也就是說如果網頁檔案中出現大量的類似‘th:’的語法規則,提供不同資料來組合成一個完整的使用者檢視介面。
輸出結果:
設定模板字首和字尾
簡化引用模板檔案所在路徑及副檔名操作。其中字首就是相當於類路徑下的一個目錄名稱,字尾是檔案的副檔名。
在resources下新建資料夾templates,再在裡面新建模板檔案main.html(內容上同)。
編寫測試方法:
@Test
public void test3() {
TemplateEngine engine = new TemplateEngine();
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
// 在類路徑下的templates目錄找字尾為html的main檔案
resolver.setPrefix("templates/");
resolver.setSuffix(".html");
engine.setTemplateResolver(resolver);
Context context = new Context();
context.setVariable("name", "張三");
String result = engine.process("main", context);
System.out.println("模板檔案渲染結果==> " + result);
}
注意別少了“templates/”後邊的‘/’!
輸出結果:
以上是在一個非web專案中如何使用thymeleaf模板引擎,只是簡單介紹。 但在開發中大多還是以web工程為主流,所以需學習和掌握基礎語法和使用技巧,熟練運用並實踐。
_______________________________________________________________________________________
Thymeleaf參考手冊(十三):文字模板模式
https://zhuanlan.zhihu.com/p/183821971
在Thymeleaf的三種模板模式被認為是文字:TEXT,JAVASCRIPT和CSS。這將它們與標記模板模式區分開:HTML和 XML。
文字模板模式和標記模式之間的主要區別在於,在文字模板中,沒有標籤可以插入屬性形式的邏輯,因此我們必須依靠其他機制。
這些機制的第一個也是最基本的是內聯的,我們已經在上一章中進行了詳細介紹。內聯語法是在文字模板模式下輸出表示式結果的最簡單方法,因此,這是文字電子郵件完美有效的模板。
Dear [(${name})],
Please find attached the results of the report you requested
with name "[(${report.name})]".
Sincerely,
The Reporter.
即使沒有標籤,上面的示例也是一個完整且有效的Thymeleaf模板,可以在 TEXT 模板模式下執行。
但是,為了包含比單純的輸出表示式更復雜的邏輯,我們需要一種新的非基於標記的語法:
[# th:each="item : ${items}"]
- [(${item})]
[/]
實際上是更冗長的精簡版本:
[#th:block th:each="item : ${items}"]
- [#th:block th:utext="${item}" /]
[/th:block]
請注意,這種新語法是如何基於宣告為的元素(即可處理標籤)[#element ...] 而不是 <element ...>。元素以 [#element ...] 開頭,以 [/element] 閉合,並且可以透過 / 將開始元素最小化來宣告獨立標籤,該方式幾乎等同於XML標籤:[#element ... /]。
標準方言僅包含用於以下元素之一的處理器:th:block,儘管我們可以在方言中對此進行擴充套件並以通常的方式建立新元素。另外,th:block 元素([#th:block ...] ... [/th:block])可以縮寫為空字串([# ...] ... [/]),因此上述程式碼塊實際上等效於:
[# th:each="item : ${items}"]
- [# th:utext="${item}" /]
[/]
給定 [# th:utext="${item}" /] 等效於內聯的未轉義表示式,我們可以使用它來減少程式碼量。因此,我們結束了上面看到的程式碼的第一個片段:
[# th:each="item : ${items}"]
- [(${item})]
[/]
請注意,文字語法要求元素對稱(沒有未關閉的標籤)和帶引號的屬性 – XML樣式比HTML樣式更多。
我們來看一個更完整的TEXT模板示例,即純文字電子郵件模板:
Dear [(${customer.name})],
This is the list of our products:
[# th:each="prod : ${products}"]
- [(${prod.name})]. Price: [(${prod.price})] EUR/kg
[/]
Thanks,
The Thymeleaf Shop
執行後,其結果可能類似於:
Dear Mary Ann Blueberry,
This is the list of our products:
- Apricots. Price: 1.12 EUR/kg
- Bananas. Price: 1.78 EUR/kg
- Apples. Price: 0.85 EUR/kg
- Watermelon. Price: 1.91 EUR/kg
Thanks,
The Thymeleaf Shop
JAVASCRIPT 模板模式下的另一個示例(greeter.js檔案)將作為文字模板進行處理,然後從HTML頁面呼叫該結果。請注意,這不是HTML模板中的 <script> 塊,而是 .js 單獨作為模板處理的檔案:
var greeter = function() {
var username = [[${session.user.name}]];
[# th:each="salut : ${salutations}"]
alert([[${salut}]] + " " + username);
[/]
};
執行後,其結果可能類似於:
var greeter = function() {
var username = "Bertrand \"Crunchy\" Pear";
alert("Hello" + " " + username);
alert("Ol\u00E1" + " " + username);
alert("Hola" + " " + username);
};
轉義元素屬性
為了避免與模板的其他部分可能會以其他方式處理的互動(例如,HTML模板內的文字模式),Thymeleaf 3.0允許轉義其文字語法中元素的屬性。所以:
- TEXT 模板模式下的屬性將採用HTML轉義。
- JAVASCRIPT 模板模式下的屬性將是JavaScript非轉義的。
- CSS 模板模式下的屬性將採用CSS換碼。
因此,這在文字模式模板中是完全可以的(請注意 >):
[# th:if="${120<user.age}"]
Congratulations!
[/]
當然,< 在實際的文字模板中這沒有任何意義,但是如果我們用包含上面程式碼的th:inline="text" 程式碼塊來處理HTML模板,並且希望確保我們的瀏覽器在靜態開啟檔案作為原型時,不使用 <user.age 作為起始標記的名稱。
可擴充套件性
這種語法的優點之一是它與標記語法一樣可擴充套件。開發人員仍然可以使用自定義元素和屬性來定義自己的方言,為它們應用字首(可選),然後在文字模板模式下使用它們:
[#myorg:dosomething myorg:importantattr="211"]some text[/myorg:dosomething]
純文字原型註釋塊:新增程式碼
在JAVASCRIPT 和 CSS 模板模式(不適用於 TEXT),允許包括一個特殊的註釋語法之間的程式碼 /*[+...+]*/,這樣Thymeleaf會處理模板時自動取消註釋這樣的程式碼:
var x = 23;
/*[+
var msg = "This is a working application";
+]*/
var f = function() {
...
將解析為:
var x = 23;
var msg = "This is a working application";
var f = function() {
...
也可以在這些註釋中包含表示式,它們將被評估:
var x = 23;
/*[+
var msg = "Hello, " + [[${session.user.name}]];
+]*/
var f = function() {
...
文字解析器級註釋塊:刪除程式碼
在類似於僅原型的註釋塊的方式,所有三個文字模板模式(TEXT,JAVASCRIPT 和 CSS)使其能夠指示Thymeleaf特殊之間移除程式碼/*[- */ 和 /* -]*/ 標誌,就像這樣:
var x = 23;
/*[- */
var msg = "This is shown only when executed statically!";
/* -]*/
var f = function() {
...
或在 TEXT 模式下:
...
/*[- Note the user is obtained from the session, which must exist -]*/
Welcome [(${session.user.name})]!
...
自然的JavaScript和CSS模板
如之前所述,JavaScript和CSS內聯提供了將內聯表示式包含在JavaScript / CSS註釋中的可能性,例如:
...
var username = /*[[${session.user.name}]]*/ "Sebastian Lychee";
...
解析後結果為:
...
var username = "John Apricot";
...
實際上,可以將這種將內聯表示式包含在註釋中的相同技巧可用於整個文字模式語法:
/*[# th:if="${user.admin}"]*/
alert('Welcome admin');
/*[/]*/
如果模板是靜態開啟的(因為它是100%有效的JavaScript),並且如果使用者是管理員執行模板,則將在上面的程式碼中顯示該警報。它等效於:
[# th:if="${user.admin}"]
alert('Welcome admin');
[/]
實際上是模板解析期間初始版本轉換成的程式碼。
但是請注意,註釋行中的換行元素不會像內聯表示式那樣,清除其所在的行(直到一直在右邊找到a ;為止)。這種行為只適用於內聯輸出表示式。