這節主要介紹模板的引入。及如何在不改變前端人員的html顯示結果的情況下設計模板(通過屬性配置動態時不顯示的部分)。
模板模塊導入
首先定義一個/WEBINF/templates/footer.html文件:
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</div>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
上面的代碼定義了一個片段稱爲copy,我們可以很容易地使用th:include 或者 th:replace屬性包含在我們的主頁上:
<body>
...
<div th:include="footer :: copy"></div>
</body>
- 1
- 2
- 3
- 4
include的表達式想當簡潔。這裏有三種寫法:
- “templatename::domselector” 或者 “templatename::[domselector]”引入模板頁面中的某個模塊。
- “templatename”引入模板頁面。
- “::domselector” 或者 “this::domselector” 引入自身模板的模塊
上面所有的templatename和domselector的寫法都支持表達式寫法:
<div th:include="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div>
- 1
不使用th:fragment來引用模塊
...
<div id="copy-section">
© 2011 The Good Thymes Virtual Grocery
</div>
...
- 1
- 2
- 3
- 4
- 5
我們可以用css的選擇器寫法來引入
<body>
...
<div th:include="footer :: #copy-section"></div>
</body>
- 1
- 2
- 3
- 4
th:include 和 th:replace的區別
th:include和th:replace都可以引入模塊,兩者的區別在於
th:include:引入子模塊的children,依然保留父模塊的tag。
th:replace:引入子模塊的所有,不保留父模塊的tag。
舉個栗子:
<footer th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</footer>
- 1
- 2
- 3
引入界面:
<body>
...
<div th:include="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
</body>
- 1
- 2
- 3
- 4
- 5
結果是:
<body>
...
<div>
© 2011 The Good Thymes Virtual Grocery
</div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</body>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
給引入模塊添加參數
我們的模塊當中肯定有需要有參數的需求:
<div th:fragment="frag (onevar,twovar)">
<p th:text="${onevar} + ' - ' + ${twovar}">...</p>
</div>
- 1
- 2
- 3
比如在文本中顯示參數可以這樣中:
<div th:include="::frag (${value1},${value2})">...</div>
<div th:include="::frag (onevar=${value1},twovar=${value2})">...</div>
- 1
- 2
第二種用法中參數順序並不重要:
<div th:include="::frag (twovar=${value2},onevar=${value1})">...</div>
- 1
引入沒有被定義的模塊參數
這段模塊沒有定義參數
<div th:fragment="frag">
...
</div>
- 1
- 2
- 3
我們可以並且只能用第二種方式引入:
<div th:include="::frag (onevar=${value1},twovar=${value2})">
- 1
這個也等同於:
<div th:include="::frag" th:with="onevar=${value1},twovar=${value2}">
- 1
解析式刪除不需要的內容(這纔是此技術最吸引人的地方,可以讓前端和後端使用同一個模板,並且都能看到自己想要的效果)
一般情況下後端處理後的界面是這樣的:
<table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
<th>COMMENTS</th>
</tr>
<tr th:each="prod : ${prods}" th:class="${prodStat.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>
<td>
<span th:text="${#lists.size(prod.comments)}">2</span> comment/s
<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:unless="${#lists.isEmpty(prod.comments)}">view</a>
</td>
</tr>
</table>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
這只是個模板文件,不是前端寫好的預覽文件,那麼要和前端寫好的預覽文件一至,我們一般情況下只能增加虛擬的行.
<table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
<th>COMMENTS</th>
</tr>
<tr th:each="prod : ${prods}" th:class="${prodStat.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>
<td>
<span th:text="${#lists.size(prod.comments)}">2</span> comment/s
<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:unless="${#lists.isEmpty(prod.comments)}">view</a>
</td>
</tr>
<tr class="odd">
<td>Blue Lettuce</td>
<td>9.55</td>
<td>no</td>
<td>
<span>0</span> comment/s
</td>
</tr>
<tr>
<td>Mild Cinnamon</td>
<td>1.99</td>
<td>yes</td>
<td>
<span>3</span> comment/s
<a href="comments.html">view</a>
</td>
</tr>
</table
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
OK.現在我們有三行了。看起來和前端的預覽文件一致了。那麼我們通過thymeleaf處理後的結果肯定是正確的內容+虛擬的內容,其實我們要的只是正確的內容而已。
爲了解決這個問題th:remove華麗登場了。
<table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
<th>COMMENTS</th>
</tr>
<tr th:each="prod : ${prods}" th:class="${prodStat.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>
<td>
<span th:text="${#lists.size(prod.comments)}">2</span> comment/s
<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:unless="${#lists.isEmpty(prod.comments)}">view</a>
</td>
</tr>
<tr class="odd" th:remove="all">
<td>Blue Lettuce</td>
<td>9.55</td>
<td>no</td>
<td>
<span>0</span> comment/s
</td>
</tr>
<tr th:remove="all">
<td>Mild Cinnamon</td>
<td>1.99</td>
<td>yes</td>
<td>
<span>3</span> comment/s
<a href="comments.html">view</a>
</td>
</tr>
</table>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
這個模板在後端開發通過thymeleaf解析後會移除掉有th:remove的標籤,滿足後端的預期。同時在前端眼中,也是自己預覽的效果。
th:remove總共有五種屬性:
- all : 移除tag標記和children。
- body:保留tag標記和移除children。
- tag :移除tag和保留children.
- all-but-first :保留tag和移除除了第一個外的所有children。
- none :什麼都不做。
以下是all-but-first的栗子:
<table>
<thead>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
<th>COMMENTS</th>
</tr>
</thead>
<tbody th:remove="all-but-first">
<tr th:each="prod : ${prods}" th:class="${prodStat.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>
<td>
<span th:text="${#lists.size(prod.comments)}">2</span> comment/s
<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:unless="${#lists.isEmpty(prod.comments)}">view</a>
</td>
</tr>
<tr class="odd">
<td>Blue Lettuce</td>
<td>9.55</td>
<td>no</td>
<td>
<span>0</span> comment/s
</td>
</tr>
<tr>
<td>Mild Cinnamon</td>
<td>1.99</td>
<td>yes</td>
<td>
<span>3</span> comment/s
<a href="comments.html">view</a>
</td>
</tr>
</tbody>
</table>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
當然屬性也支持表達式:
<a href="/something" th:remove="${condition}? tag : none">Link text not to be removed</a>
- 1
<a href="/something" th:remove="${condition}? tag">Link text not to be removed</a>
- 1