Thymeleaf教程 (八) 模板佈局(thymeleaf的主要技術優點)

這節主要介紹模板的引入。及如何在不改變前端人員的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">
            &copy; 2011 The Good Thymes Virtual Grocery
        </div>
    </body>
</html>

上面的代碼定義了一個片斷稱爲copy,咱們能夠很容易地使用th:include 或者 th:replace屬性包含在咱們的主頁上:前端

<body>
...
<div th:include="footer :: copy"></div>
</body>

include的表達式想當簡潔。這裏有三種寫法:後端

  • 「templatename::domselector」 或者 「templatename::[domselector]」引入模板頁面中的某個模塊。
  • 「templatename」引入模板頁面。
  • 「::domselector」 或者 「this::domselector」 引入自身模板的模塊 
    上面全部的templatename和domselector的寫法都支持表達式寫法:
<div th:include="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div>

不使用th:fragment來引用模塊

...
<div id="copy-section">
&copy; 2011 The Good Thymes Virtual Grocery
</div>
...

咱們能夠用css的選擇器寫法來引入less

<body>
...
<div th:include="footer :: #copy-section"></div>
</body>

th:include 和 th:replace的區別

th:include和th:replace均可以引入模塊,二者的區別在於 
th:include:引入子模塊的children,依然保留父模塊的tag。 
th:replace:引入子模塊的全部,不保留父模塊的tag。 
舉個栗子:dom

<footer th:fragment="copy">
&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>
&copy; 2011 The Good Thymes Virtual Grocery
</div>
<footer>
&copy; 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總共有五種屬性:

  • 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>

固然屬性也支持表達式:

<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>
相關文章
相關標籤/搜索