Thymeleaf 模板布局

官方文档: https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html

1.定义模板片段

定义和引用片段


在我们的页面中,我们经常需要包含其他模板中的部分,页脚,标题,菜单等部分......

为了做到这一点,Thymeleaf 需要我们定义这些部分,“片段”,以便包含,这可以使用th:fragment属性来完成

假设我们现在要定义一个模板页脚,因此我们创建一个/templates/footer.html包含以下代码文件:

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

  <body>
  
    <font th:fragment="footer">
      &copy; 2011 The Good Thymes Virtual Grocery
    </font>
  
  </body>
  
</html>

说明:th:fragment="footer"  定义模板为 footer

上面的代码定义了一个名称为footer的片段,我们可以th:replace属性轻松地在我们的主页中引用这些片段

<body><div th:insert="~{footer :: footer}"></div>
  
</body>

说明:th:insert="~{footer :: footer}" 引用footer 页面的footer模板,也可以写为 th:insert="footer :: copy"

页面运行效果:

或者

我们可以包含不使用任何th:fragment属性的片段

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

  <body>
  
    <div id="footer">
      &copy; 2012 The Good Thymes Virtual Grocery
    </div>
  
  </body>
  
</html>

我们可以使用上面的片段简单地通过其 id属性引用它,类似于CSS选择器:

<body>

  <div th:insert="~{footer :: #copy-section}"></div>
  
</body>

页面运行效果:

 

th:insertth:replace之间的区别


 

  • th:insert 是最简单的:它只是插入指定的片段作为其主机标签的主体。

  • th:replace实际上指定的片段替换它的主机标签。

<body>

  <div th:insert="footer :: copy"></div>

  <div th:replace="footer :: #copy"></div>
  
</body>

 页面运行效果:

 

2.可参数化的片段

为了为模板片段创建更像函数的机制,使用定义的片段th:fragment可以指定一组参数

<div th:fragment="frag (onevar,twovar)">
    <p th:text="${onevar} + ' - ' + ${twovar}">...</p>
</div>

这需要用 th:insert调用片段th:replace

<div th:replace="::frag (${value1},${value2})">...</div>
<div th:replace="::frag (onevar=${value1},twovar=${value2})">...</div>

请注意,顺序在最后一个选项中可变

<div th:replace="::frag (twovar=${value2},onevar=${value1})">...</div>

调用片段局部变量没有片段参数

<div th:fragment="frag">
    ...
</div>

假设,现在调用局部变量时发没有片段参数,只能

<div th:replace="::frag (onevar=${value1},twovar=${value2})">

这将相当于组合th:replaceth:with

<div th:replace="::frag" th:with="onevar=${value1},twovar=${value2}">

3.灵活的布局

定义模板

<head th:fragment="common_header(title,links)">

  <title th:replace="${title}">The awesome application</title>

  <!-- Common styles and scripts -->
  <link rel="stylesheet" type="text/css" media="all" th:href="@{/css/awesomeapp.css}">
  <link rel="shortcut icon" th:href="@{/images/favicon.ico}">
  <script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"></script>

  <!--/* Per-page placeholder for additional links */-->
  <th:block th:replace="${links}" />

</head>

引用模板

<head th:replace="base :: common_header(~{::title},~{::link})">

  <title>Awesome - Main</title>

  <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
  <link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}">

</head>

说明:th:replace="base :: common_header(~{::title},~{::link})" 引用模板传参数,

也可以不传(th:replace="base :: common_header(~{::title},~{})),

如果模板参数片段有默认值了,你想使用默认值,如果使用无操作(th:replace="base :: common_header(_,~{::link})"

页面运行效果:

4.删除模板片段

产品列表模板

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

为什么会有删除模板片段呢,如果当浏览器直接打开而没有Thymeleaf处理它时,因为虽然浏览器可以完全显示,但该表只有一行。

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

如果在后面追加静态数据时,不管有没有Thymeleaf处理它时,数据都会显示数据出来。

那么问题来了,怎么才能没有Thymeleaf处理它显示静态数据,有没有Thymeleaf处理它时不显示静态数据呢。

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

all属性中的这个值是什么意思?th:remove可以根据其价值以五种不同的方式表现:

  • all:删除包含标记及其所有子标记。
  • body:不要删除包含标记,但删除其所有子标记。
  • tag:删除包含标记,但不删除其子项。
  • all-but-first:删除除第一个之外的所有包含标记的子项。
  • none: 没做什么。(可以通过判断要不要显示出来此值对于动态评估很有用。

th:remove属性可采取任何Thymeleaf标准表示,因为它返回允许字符串值中的一个,只要(alltagbodyall-but-firstnone)。

这意味着删除可能是有条件的,例如:

<a href="/something" th:remove="${condition}? tag : none">Link text not to be removed</a>

另请注意,th:remove考虑null同义词none,因此以下工作方式与上面的示例相同:

<a href="/something" th:remove="${condition}? tag">Link text not to be removed</a>

在这种情况下,如果${condition}为false,null将返回,因此不会执行删除。

5.布局继承

为了能够将单个文件作为布局,可以使用片段。具有titlecontent使用th:fragment的简单布局的示例

<!DOCTYPE html>
<html th:fragment="layout (title, content)" xmlns:th="http://www.thymeleaf.org">
<head>
    <title th:replace="${title}">Layout Title</title>
</head>
<body>
    <h1>Layout H1</h1>
    <div th:replace="${content}">
        <p>Layout content</p>
    </div>
    <footer>
        Layout footer
    </footer>
</body>
</html>

此示例声明了一个名为layout的片段,其中titlecontent作为参数。两者都将在页面上替换,并在下面的示例中通过提供的片段表达式继承它。

<!DOCTYPE html>
<html th:replace="~{layoutFile :: layout(~{::title}, ~{::section})}">
<head>
    <title>Page Title</title>
</head>
<body>
<section>
    <p>Page content</p>
    <div>Included on page</div>
</section>
</body>
</html>

结果:


在传参数时,可以通过运算来传不同的值。

文章的数据都是来自于    Thymeleaf官网的 8 Template Layout

猜你喜欢

转载自www.cnblogs.com/mylhy/p/10945478.html