thymeleaf 公共模板布局
片段引入
在 Thymeleaf 中,我们可以使用以下 3 个属性,将公共页面片段引入到当前页面中。
- th:insert:将代码块片段整个插入到使用了 th:insert 属性的 HTML 标签中;
- th:replace:将代码块片段整个替换使用了 th:replace 属性的 HTML 标签中;
th:include:将代码块片段包含的内容插入到使用了 th:include 属性的 HTML 标签中。
使用上 3 个属性引入页面片段,都可以通过以下 2 种方式实现。
- ~{templatename::#selector}:模板名::选择器
- ~{templatename::fragmentname}:模板名::片段名
通常情况下,~{} 可以省略
实例
- 在页面 fragment.html 中引入 commons.html 中声明的页面片段,可以通过以下方式实现
<!--th:insert 片段名引入-->
<div th:insert="commons::fragment-name"> </div>
<!--th:insert id 选择器引入-->
<div th:insert="commons::#fragment-id"> </div>
------------------------------------------------
<!--th:replace 片段名引入-->
<div th:replace="commons::fragment-name"> </div>
<!--th:replace id 选择器引入-->
<div th:replace="commons::#fragment-id"> </div>
------------------------------------------------
<!--th:include 片段名引入-->
<div th:include="commons::fragment-name"> </div>
<!--th:include id 选择器引入-->
<div th:include="commons::#fragment-id"> </div>
- 效果如下
<!--th:insert 片段名引入-->
<div>
<div id="fragment-id">
<span>公共页面片段</span>
</div>
</div>
<!--th:insert id 选择器引入-->
<div>
<div id="fragment-id">
<span>公共页面片段</span>
</div>
</div>
<!--th:replace 片段名引入-->
<div id="fragment-id">
<span>公共页面片段</span>
</div>
<!--th:replace id 选择器引入-->
<div id="fragment-id">
<span>公共页面片段</span>
</div>
<!--th:include 片段名引入-->
<div>
<span>公共页面片段</span>
</div>
<!--th:include id 选择器引入-->
<div>
<span>公共页面片段</span>
</div>
可参数化片段签名
为了为模板片段创建一个更像函数的th:fragment
机制,定义的片段可以指定一组参数:
<div th:fragment="frag (onevar,twovar)">
<p th:text="${onevar} + ' - ' + ${twovar}">...</p>
</div>
这需要使用这两种语法之一来从th:insert
or调用片段th:replace
:
<div th:replace="::frag (${value1},${value2})">...</div>
<div th:replace="::frag (onevar=${value1},twovar=${value2})">...</div>
灵活的布局:不仅仅是片段插入
多亏了片段表达式,我们可以为片段指定参数,这些片段不是文本、数字、bean 对象……而是标记片段。
这使我们能够以一种方式创建我们的片段,以便可以使用来自调用模板的标记来丰富它们,从而产生非常灵活的模板布局机制。
请注意以下片段中的title
和links
变量的使用:
<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>
...
…结果将使用我们调用模板中的实际<title>
和标记作为和变量的值,从而导致我们的片段在插入期间被定制:<link>``title``links
...
<head>
<title>Awesome - Main</title>
<!-- Common styles and scripts -->
<link rel="stylesheet" type="text/css" media="all" href="/awe/css/awesomeapp.css">
<link rel="shortcut icon" href="/awe/images/favicon.ico">
<script type="text/javascript" src="/awe/sh/scripts/codebase.js"></script>
<link rel="stylesheet" href="/awe/css/bootstrap.min.css">
<link rel="stylesheet" href="/awe/themes/smoothness/jquery-ui.css">
</head>
...
使用空片段
一个特殊的片段表达式,空片段( ~{}
),可用于指定无标记。使用前面的示例:
<head th:replace="base :: common_header(~{::title},~{})">
<title>Awesome - Main</title>
</head>
...
请注意片段的第二个参数 ( links
) 是如何设置为空片段的,因此没有为<th:block th:replace="${links}" />
块写入任何内容:
...
<head>
<title>Awesome - Main</title>
<!-- Common styles and scripts -->
<link rel="stylesheet" type="text/css" media="all" href="/awe/css/awesomeapp.css">
<link rel="shortcut icon" href="/awe/images/favicon.ico">
<script type="text/javascript" src="/awe/sh/scripts/codebase.js"></script>
</head>
...
更多详解参考官方文档:
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html