SpringBoot搭建个人博客系统项目4:使用thymeleaf抽取页面的公共片段

thymeleaf简单使用

thymeleaf是SpringBoot默认集成的模板引擎

表达式

${...}: 变量表达式。
*{...} : 选择表达式。
#{...} : 消息 (i18n) 表达式。
@{...} : 链接 (URL) 表达式。
~{...} : 片段表达式。

使用thymeleaf抽取公共片段

使用th:fragment="xx"来抽取某个页面的片段

<div th:fragment="copy">

</div>

使用th:insert="~{page::xx}"来引入从page中抽取的片段

<div th:insert="~{dashboard::copy}">

</div>

此时抽取部分被包含在一个div中。有可能造成排版错乱

三种引入片段的属性
th:insert:将公共的片段整个插入指定元素中
th:replace:将声明引入的元素替换为公共片段(符合理想情况)
th:include:将被引入公共片段的内容插入到指定的元素中

如果使用th:insert属性引入则可以不用写~{},例如th:insert="dashboard::copy"
而行内写法则必须加上~{}[[~{}]][(~{})]

还可以不使用th:fragment抽取公共部分,在引入的页面中使用th:replace="~{template::#selector}"即可

在博客系统中抽取公共片段

以首页为例,其它页面用法稍有不同。

新建一个admin_fragments.html,存放admin文件夹中页面的公共部分;
新建一个fragments.html页面,里面保存公共片段。
将这两个文件统一放到templates下的commons文件夹下。

CSS样式

先将所有页面引入的css保存起来,在别的页面引入时,只需要传入参数改变页面的title属性即可。
fragments.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:fragment="head(title)">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>[[${title}]]</title>
    <link rel="stylesheet" href="/css/me.css" th:href="@{/css/me.css}">
    <link rel="stylesheet" href="/css/typo.css" th:href="@{/css/typo.css}">
    <link rel="stylesheet" href="/lib/editormd/css/editormd.css" th:href="@{/lib/editormd/css/editormd.css}" />
    <link rel="stylesheet" href="/lib/tocbot/tocbot.css" th:href="@{/lib/tocbot/tocbot.css}">
    <link rel="stylesheet" href="/lib/prism/prism.css" th:href="@{/lib/prism/prism.css}">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.css">
</head>
<body>
</body>
</html>

在首页传入titile的值为'首页',则页面标题为"首页",例如:
index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="_fragments::head('首页')"></head>
<body>
...
</body>
</html>

导航栏

大部分页面(除博客管理和写博客页面)的头部是一样的,只是active的地方不同而已。
fragments.html

<body>
<!-- 导航 -->
<nav th:fragment="menu(index)" class="ui inverted attached segment m-padding-tb-mini m-shadow-small" id="header">
    <div class="ui container m-container-large">
        <div class="ui inverted secondary stackable menu">
            <h2 class="ui teal header item m-header">Yonmin</h2>
            <a href="/" class="m-item item m-mobile-hide" th:classappend="${index=='首页'} ? 'active'"><i class="home icon"></i>首页</a>
            <a href="types" class="m-item item m-mobile-hide" th:classappend="${index=='分类'} ? 'active'"><i class="idea icon"></i>分类</a>
            <a href="tags" class="m-item item m-mobile-hide" th:classappend="${index=='标签'} ? 'active'"><i class="tags icon"></i>标签</a>
            <a href="archives" class="m-item item m-mobile-hide" th:classappend="${index=='归档'} ? 'active'"><i class="clone icon"></i>归档</a>
            <a href="about" class="m-item item m-mobile-hide" th:classappend="${index=='关于我'} ? 'active'"><i class="info icon"></i>关于我</a>
            <div class="right item m-item m-mobile-hide m-margin-tb-small">
                <div class="ui icon inverted transparent input">
                    <input type="text" placeholder="Search...">
                    <i class="search link icon"></i>
                </div>
            </div>
        </div>
    </div>
    <a href="#" class="ui button black icon m-top-right m-mobile-show show">
        <i class="sidebar icon"></i>
    </a>
</nav>

根据传入的index值选择在哪个元素的class中添加active,因此只需要在页面传入相应的值即可。
例如首页写<head th:replace="_fragments::head('首页')"></head>
分类页写<head th:replace="_fragments::head('分类')"></head>

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="_fragments::head('首页')"></head>
<body>
<!-- 导航 -->
<div th:replace="_fragments::menu('首页')"></div>

...
<body>
</html>

底部 footer

底部footer除了博客管理页面(因为无用所以我将其删除了)和写博客页面外的所有页面都是一样的,只需要抽取后直接在页面内引入。
fragments.html

<!-- 底部footer -->
<footer th:fragment="footer" id="footer" class="ui inverted vertical segment m-padding-tb-massive">
    <div class="ui center aligned container m-container-large">
        <div class="ui grid stackable inverted divided">
            <div class="three wide column">
                <div class="ui inverted link list">
                    <div class="item">
                        <img src="images/wechat.jpg" class="ui rounded image" style="width: 110px">
                    </div>
                </div>
            </div>

            <div class="three wide column">
                <h4 class="ui inverted header m-opacity-mini">最新博客</h4>
                <div class="ui inverted link list">
                    <a href="#" class="item">用户故事</a>
                    <a href="#" class="item">用户故事</a>
                    <a href="#" class="item">用户故事</a>
                </div>
            </div>

            <div class="three wide column">
                <h4 class="ui inverted header m-opacity-mini">联系我</h4>
                <div class="ui inverted link list">
                    <a href="#" class="item">Email:2@qq.com</a>
                    <a href="#" class="item">WeChat:YonminMa</a>
                    <a href="#" class="item">QQ:2</a>
                </div>
            </div>

            <div class="seven wide column">
                <h4 class="ui inverted header m-opacity-mini">Blog</h4>
                <p class="m-text-thin m-text-spaced m-opacity-mini">这是我的个人博客、分享关于编程、写作、思考相关的任何内容,希望可以给来这儿的人一点帮助。。。</p>
            </div>
        </div>
        <div class="ui inverted section divider"></div>
        <p class="m-text-thin m-text-spaced m-opacity-tiny">Copyright © 2012-2020 Yonmin. All Rights Reserved.</p>
    </div>
</footer>

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="_fragments::head('首页')"></head>
<body>

<!-- 导航 -->
<div th:replace="_fragments::menu('首页')"></div>

...

<!-- 底部footer -->
<div th:replace="_fragments::footer"></div>

...

</body>
</html>

admin_fragments.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:fragment="head(title)">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>[[${title}]]</title>
    <link rel="stylesheet" href="/css/me.css" th:href="@{/css/me.css}">
    <link rel="stylesheet" href="/css/typo.css" th:href="@{/css/typo.css}">
    <link rel="stylesheet" href="/lib/editormd/css/editormd.css" th:href="@{/lib/editormd/css/editormd.css}">
    <link rel="stylesheet" href="/lib/tocbot/tocbot.css" th:href="@{/lib/tocbot/tocbot.css}">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.css">
</head>
<body>
<nav th:fragment="menu(index)" class="ui inverted attached segment m-padding-tb-mini m-shadow-small" id="header">
    <div class="ui container m-container-large">
        <div class="ui inverted secondary stackable menu">
            <h2 class="ui teal header item m-header">Yonmin</h2>
            <a href="#" class="m-item item m-mobile-hide" th:classappend="${index=='博客'} ? 'active'"><i class="home icon"></i>博客</a>
            <a href="#" class="m-item item m-mobile-hide" th:classappend="${index=='分类'} ? 'active'"><i class="idea icon"></i>分类</a>
            <a href="#" class="m-item item m-mobile-hide" th:classappend="${index=='标签'} ? 'active'"><i class="tags icon"></i>标签</a>
            <div class="right m-item m-mobile-hide menu">
                <div class="ui dropdown item">
                    <img src="https://tse4-mm.cn.bing.net/th/id/OIP.Ie53C-X76KBg5Yr5rf6JbgHaDe?w=318&h=164&c=7&o=5&pid=1.7" alt="" class="ui avatar image">
<!--                    <div>Yonmin</div>-->
<!--                    <i class="dropdown icon"></i>-->
                    <div class="menu">
                        <a href="/admin/logout" class="item">注销</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <a href="#" class="ui button black icon m-top-right m-mobile-show show">
        <i class="sidebar icon"></i>
    </a>
</nav>
</body>
</html>

对导航栏样式做了少许修改。
使用时用例如<div th:replace="commons/admin_fragments::menu('博客')"></div>引用。

引入的js资源也是可以抽取的,但是不多,我就没弄,有需要的朋友可以自己抽取一下。

此更新已提交至此项目的Github,欢迎star

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值