官方文档: 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"> © 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"> © 2012 The Good Thymes Virtual Grocery </div> </body> </html>
我们可以使用上面的片段简单地通过其 id
属性引用它,类似于CSS选择器:
<body> <div th:insert="~{footer :: #copy-section}"></div> </body>
页面运行效果:
th:insert
和th: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:replace
和th: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标准表示,因为它返回允许字符串值中的一个,只要(all
,tag
,body
,all-but-first
或none
)。
这意味着删除可能是有条件的,例如:
<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.布局继承
为了能够将单个文件作为布局,可以使用片段。具有title
和content
使用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的片段,其中title和content作为参数。两者都将在页面上替换,并在下面的示例中通过提供的片段表达式继承它。
<!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