這節主要介紹模板的引入。及如何在不改變前端人員的html顯示結果的狀況下設計模板(經過屬性配置動態時不顯示的部分)。css
首先定義一個/WEBINF/templates/footer.html文件: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>
上面的代碼定義了一個片斷稱爲copy,咱們能夠很容易地使用th:include 或者 th:replace屬性包含在咱們的主頁上:前端
<body> ... <div th:include="footer :: copy"></div> </body>
include的表達式想當簡潔。這裏有三種寫法:後端
<div th:include="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div>
... <div id="copy-section"> © 2011 The Good Thymes Virtual Grocery </div> ...
咱們能夠用css的選擇器寫法來引入less
<body> ... <div th:include="footer :: #copy-section"></div> </body>
th:include和th:replace均可以引入模塊,二者的區別在於
th:include:引入子模塊的children,依然保留父模塊的tag。
th:replace:引入子模塊的全部,不保留父模塊的tag。
舉個栗子:dom
<footer th:fragment="copy"> © 2011 The Good Thymes Virtual Grocery </footer>
引入界面:this
<body> ... <div th:include="footer :: copy"></div> <div th:replace="footer :: copy"></div> </body>
結果是:spa
<body> ... <div> © 2011 The Good Thymes Virtual Grocery </div> <footer> © 2011 The Good Thymes Virtual Grocery </footer> </body>
咱們的模塊當中確定有須要有參數的需求:設計
<div th:fragment="frag (onevar,twovar)"> <p th:text="${onevar} + ' - ' + ${twovar}">...</p> </div>
好比在文本中顯示參數能夠這樣中:code
<div th:include="::frag (${value1},${value2})">...</div> <div th:include="::frag (onevar=${value1},twovar=${value2})">...</div>
第二種用法中參數順序並不重要:
<div th:include="::frag (twovar=${value2},onevar=${value1})">...</div>
這段模塊沒有定義參數
<div th:fragment="frag"> ... </div>
咱們能夠而且只能用第二種方式引入:
<div th:include="::frag (onevar=${value1},twovar=${value2})">
這個也等同於:
<div th:include="::frag" th:with="onevar=${value1},twovar=${value2}">
通常狀況下後端處理後的界面是這樣的:
<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>
這只是個模板文件,不是前端寫好的預覽文件,那麼要和前端寫好的預覽文件一至,咱們通常狀況下只能增長虛擬的行.
<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
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>
這個模板在後端開發經過thymeleaf解析後會移除掉有th:remove的標籤,知足後端的預期。同時在前端眼中,也是本身預覽的效果。
th:remove總共有五種屬性:
<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>
固然屬性也支持表達式:
<a href="/something" th:remove="${condition}? tag : none">Link text not to be removed</a>
<a href="/something" th:remove="${condition}? tag">Link text not to be removed</a>