- 对于应用中公共的头部、左侧或右侧、甚至是底部区域,只要是共用的,就无需每个页面都重复去写,应该提取出来,大家引用即可。
- JSP 可以使用 <jsp:include page=” ”...动态包含,同理 Thymeleaf 也有自己方式
thymeleaf 公共页面元素抽取
- 抽取公共片段
- 假设应用中需要一个公用的底部模块,如下所示 /templates/commonsFooter.html,使用 th:fragment 将其抽取为一个名字叫 "copy" 的代码片段,
- 以后在其它需要引用的地方可以使用 th:insert 、th:replace、th:include 等进行引用
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="copy">
网站标识码bm0100001 京ICP备05070218号 京公网安备11010202000001号
</div>
</body>
</html>
引用公共片段
三种引入公共片段的 th 属性:
<div th:insert="footer :: selector|fragmentname"></div>:将公共片段整个插入到声明引入的元素中
<div th:replace="footer :: selector|fragmentname"></div>:将声明引入的元素替换为公共片段
<div th:include="footer :: selector|fragmentname"></div>:将被引入的片段的内容包含进这个标签中
注意:selector 是选择器,如标签的id值等;fragmentname就是th:fragment 声明的片段名称
格式为 “模板名::选择器或者fragment名”
<!--1、比如抽取的公用代码片段如下-->
<footer th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</footer>
<!--2、采用如下三种方式进行引用-->
<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div>
<!--3、则三种引用方式的效果分别对应如下-->
<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>
- 注意:th:insert 、th:replace、th:include 在标签中进行引用时可以不加 “~” 符号,也可以加,如下所示:
<div th:insert="~{footer :: #copy-section}"></div>
抽取公共头部
- 新建一个公用的页面 common.html,然后将 userList.html 中的公用头部 <nav>元素剪切过来,同时进行公用代码抽取th:fragment
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--抽取公共的头部,使用 th:fragment 命名片段;
同理这个公用的文件(模板)中还可以设置其它的公用片段,如公用的左侧菜单,底部说明等-->
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="head">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"
th:text="${session.userName}">Company
name</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Sign out</a>
</li>
</ul>
</nav>
</body>
</html>
- 修改userList页面中去除本来的nav头部代码
- 重新登录跳转到用户页面
- 同理找到左侧导航栏公共代码抽取
- 放入公共模板中
- 除了 使用 th:fragment 命名片段名称标识,也可以直接根据选择器进行标识,如 id="left"
- userList中添加
可参数化片段签名,实现点击左侧导航栏菜单高亮
- 现在用户登录之后默认进入用户列表页面,所以“用户列表”菜单项应该高亮显示,点击商品销量则“商品销量”高亮
- 实现链接动态高亮的功能需要使用到 Thymeleaf 的 参数化片段签名功能,即在引入片段的时候传传递参数过去,这在以前 JSP 中使用动态包含时也是这么做的
8.2 Parameterizable fragment signatures
1)
In order to create a more function-like mechanism for template fragments, fragments defined with th:fragment can specify a set of parameters:
<div th:fragment="frag (onevar,twovar)">
<p th:text="${onevar} + ' - ' + ${twovar}">...</p>
</div>
2)
This requires the use of one of these two syntaxes to call the fragment from th:insert or th:replace :
<div th:replace="::frag (${value1},${value2})">...</div>
3)
Note that order is not important in the last option:
<div th:replace="::frag (onevar=${value1},twovar=${value2})">...</div>
<div th:replace="::frag (twovar=${value2},onevar=${value1})">...</div>
- 在 th:fragment 声明片段的时候可以同时声明参数,里面则可以使用这些参数的值
- 在 th:insert、th:replace、th:include 引用的时候就可以将参数值传递过去,传值的时候可以直接按顺序传递过去,也可以不按顺序但是按着参数名传递过去
Fragment local variables without fragment arguments
Even if fragments are defined without arguments like this:
<div th:fragment="frag">
...
</div>
We could use the second syntax specified above to call them (and only the second one):
<div th:replace="::frag (onevar=${value1},twovar=${value2})">
- 修改公共模板common.html中左侧导航代码,去除多余菜单
<!--公共部分左侧导航片段-->
<!--<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="left">-->
<nav class="col-md-2 d-none d-md-block bg-light sidebar" id="left">
<div class="sidebar-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-home">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
<polyline points="9 22 9 12 15 12 15 22"></polyline>
</svg>
用户列表
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-file">
<path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path>
<polyline points="13 2 13 9 20 9"></polyline>
</svg>
商品销量
</a>
</li>
</ul>
</div>
</nav>
- 对于根据“选择器”进行引用的,是无法声明参数的,所以 Thymeleaf 说明如下:即 th:fragment 或者 选择器 可以不用声明参数,而在引用的时候可以直接通过参数名将值传过去
Fragment local variables without fragment arguments
Even if fragments are defined without arguments like this:
<div th:fragment="frag">
...
</div>
We could use the second syntax specified above to call them (and only the second one):
<div th:replace="::frag (onevar=${value1},twovar=${value2})">
- 公共模块common.html修改为
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--抽取公共的头部,使用 th:fragment 命名片段;
同理这个公用的文件(模板)中还可以设置其它的公用片段,如公用的左侧菜单,底部说明等-->
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="head">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"
th:text="${session.userName}">Company
name</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Sign out</a>
</li>
</ul>
</nav>
<!--公共部分左侧导航片段-->
<!--<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="left">-->
<nav class="col-md-2 d-none d-md-block bg-light sidebar" id="left">
<div class="sidebar-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<!-- 点击用户列表链接之后,请求后台地址,th:href 的"/"表示应用根地址,必须写
使用 Thymeleaf 的三元运算符,如果 activeUri的值为 userList 则设置class的属性值为 nav-link active
否则为 nav-link,其实 active 就是 BootStrop 的高亮样式而已
-->
<a class="nav-link" th:class="${activeUri=='userList'?'nav-link active':'nav-link'}" th:href="@{/userList}" href="#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-home">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
<polyline points="9 22 9 12 15 12 15 22"></polyline>
</svg>
用户列表
</a>
</li>
<li class="nav-item">
<a class="nav-link" th:class="${activeUri=='product'?'nav-link active':'nav-link'}" th:href="@{/product}" href="#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="feather feather-file">
<path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path>
<polyline points="13 2 13 9 20 9"></polyline>
</svg>
商品销量
</a>
</li>
</ul>
</div>
</nav>
</body>
</html>
- userList.html引用通用片段时传入activeUri参数
<div th:replace="common::#left(activeUri='userList')"></div>
- product.html中引用通用片段传入activeUri参数
<div th:replace="common::#left(activeUri='product')"></div>
- 实现效果
版权声明:本文为博主原创文章,转载请附上博文链接!