Web 项目 crud 四 公共页抽取(thymeleaf布局 include replace insert)

  • 对于应用中公共的头部、左侧或右侧、甚至是底部区域,只要是共用的,就无需每个页面都重复去写,应该提取出来,大家引用即可。
  • 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">
    &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>
        &copy; 2011 The Good Thymes Virtual Grocery
    </footer>
</div>
 
<footer>
    &copy; 2011 The Good Thymes Virtual Grocery
</footer>
 
<div>
    &copy; 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>
  1. 在 th:fragment 声明片段的时候可以同时声明参数,里面则可以使用这些参数的值
  2. 在 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>

  • 实现效果

 

 


版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值