thymeleaf模板布局
1、定义和引用片段
在我们的模板中,我们经常希望包含来自其他模板的部分,如页脚、页眉、菜单……
为了做到这一点,Thymeleaf 需要我们定义这些部分,“片段”,以便包含,这可以使用th:fragment 属性来完成。
假设我们想为我们所有的杂货页面添加一个标准的版权页脚,所以我们创建一个/WEB-INF/templates/footer.html 包含以下代码的文件:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</div>
</body>
</html>
上面的代码定义了一个名为的片段,我们可以使用其中一个or属性copy 轻松地将其包含在我们的主页中(还有,尽管自 Thymeleaf 3.0 起不再推荐使用它):th:insert``th:replace``th:include
<body>
...
<div th:insert="~{footer :: copy}"></div>
</body>
请注意,它th:insert 需要一个片段表达式( ~{...} ),它是一个生成片段的表达式。在上面的例子中,它是一个非复杂的片段表达式,( ~{ , } ) 封闭是完全可选的,所以上面的代码相当于:
<body>
...
<div th:insert="footer :: copy"></div>
</body>
2、片段规范语法
片段表达式的语法非常简单。有三种不同的格式:
-
"~{templatename::selector}" 包括在名为 的模板上应用指定的标记选择器产生的片段templatename 。请注意,它selector 可能只是一个片段名称,因此您可以~{templatename::fragmentname} 像~{footer :: copy} 上面那样指定一些简单的东西。
标记选择器语法由底层 AttoParser 解析库定义,类似于 XPath 表达式或 CSS 选择器。有关详细信息,请参阅附录 C。
-
"~{templatename}" 包括名为templatename .
请注意,您在th:insert /th:replace 标签中使用的模板名称必须可由模板引擎当前使用的模板解析器解析。
-
~{::selector}" 或"~{this::selector}" 插入来自同一模板的片段,匹配selector . 如果在出现表达式的模板上找不到,则将模板调用堆栈(插入)遍历到最初处理的模板(根),直到selector 在某个级别匹配。
templatename 上面的例子和上面的例子都selector 可以是功能齐全的表达式(甚至是条件!),比如:
<div th:insert="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div>
再次注意周围的信封如何在/~{...} 中是可选的。th:insert``th:replace
片段可以包含任何th:* 属性。一旦片段被包含到目标模板(带有th:insert /th:replace 属性的那个)中,这些属性将被评估,并且它们将能够引用此目标模板中定义的任何上下文变量。
这种片段方法的一大优势是,您可以在浏览器完美显示的页面中编写片段,具有完整甚至有效的标记结构,同时仍保留使 Thymeleaf 将它们包含到其他模板中的能力。
3、没有引用片段th:fragment
由于标记选择器的强大功能,我们可以包含不使用任何th:fragment 属性的片段。它甚至可以是来自完全不了解 Thymeleaf 的不同应用程序的标记代码:
...
<div id="copy-section">
© 2011 The Good Thymes Virtual Grocery
</div>
...
我们可以使用上面的片段,简单地通过其id 属性引用它,类似于 CSS 选择器:
<body>
...
<div th:insert="~{footer :: #copy-section}"></div>
</body>
4、th:insert 和th:replace ( 和th:include )之间的区别
th:insert 和th:replace (和th:include ,自 3.0 起不推荐)有什么区别?
th:insert 是最简单的:它将简单地插入指定的片段作为其宿主标记的主体。th:replace 实际上用指定的片段替换它的主机标签。th:include 类似于th:insert ,但不是插入片段,而是仅插入该片段的内容。
所以一个像这样的 HTML 片段:
<footer th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</footer>
…在主机<div> 标签中包含 3 次,如下所示:
<body>
...
<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div>
</body>
…将导致:
<body>
...
<div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
<div>
© 2011 The Good Thymes Virtual Grocery
</div>
</body>
|