Thymeleaf 3.0教程:8 模板布局(一)
8.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>
上面的代码定义了一个名为copy的片段,我们可以使用th:insert或th:replace属性(以及th:include,尽管自Thymeleaf3.0以后不再推荐使用它)中的一个来轻松地将它包含在主页中:
<body> ... <div th:insert="~{footer :: copy}"></div> </body>
请注意,th:insert需要一个片段表达式 (~{...}),这是一个返回片段的表达式。不过,在上面的例子中,它是一个非复杂的片段表达式,所以(~{,}) 是可选的,所以上面的代码相当于:
<body> ... <div th:insert="footer :: copy"></div> </body>
片段语法规范
片段表达式的语法非常简单。有三种不同的格式:
“~{templatename::selector}”包括在名为templatename的模板上应用指定的标记选择器产生的片段。请注意,选择器可以只是一个片段名称,因此您可以指定像上面的~{footer :: copy}中那样简单的~{templatename::fragmentname}内容。
标记选择器语法由底层的AttoParser解析库定义,类似于XPath表达式或CSS选择器.
“~{templatename}”包括名为templatename的完整模板。
请注意,您在th:insert/th:replace标记中使用的模板名称必须能够由模板引擎当前使用的模板解析器解析。
~{::selector} "或" ~{this::selector} "从同一个模板插入一个片段,匹配选择器。如果在表达式出现的模板上找不到,模板调用(插入)的堆栈将向最初处理的模板(根)遍历,直到选择器在某种程度上匹配。
上面例子中的模板名和选择器都可以是全功能表达式(甚至是条件表达式!)比如:
<div th:insert="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div>
再次注意周围的~{...}信封在th:insert/th:replace中是可选的。
片段可以包括任何th:*属性。一旦片段被包含到目标模板(具有th:insert/th:replace属性的模板)中,这些属性将被评估,并且它们将能够引用在该目标模板中定义的任何上下文变量。
这种碎片处理方法的一大优势是,您可以在浏览器完全可显示的页面中编写碎片,具有完整甚至有效的标记结构,同时仍然保留将Thymeleaf包含到其他模板中的能力。
引用不带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>
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>
在host <div >标签中包含三次,如下所示:
<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>