当前位置: 首页 > news >正文

【Spring Boot】Thymeleaf模板引擎 — Thymeleaf页面布局

Thymeleaf页面布局

熟悉Thymeleaf的语法和表达式后,后面开发起来会更加得心应手。接下来好好研究一下Thymeleaf如何实现完整的Web系统页面布局。

1.引入代码片段

在模板中经常希望包含来自其他模板页面的内容,如页脚、页眉、菜单等。为了做到这一点,Thymeleaf提供了th:fragment属性。下面通过在页面中添加标准的版权页脚的场景来演示如何引入代码片段。

步骤01 定义版权页脚代码片段。

在templates目录下创建版权模板页面footer.html,示例代码如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body><div th:fragment="copyright">&copy; 2020 The Thymeleaf footer</div>
</body>
</html>

在上面的示例中,我们创建了版权页面footer.html,使用th:fragment属性定义了一个代码片段,名为copyright。

步骤02 引入代码片段模板。

创建一个普通的模板页面layout.html。使用th:insert或th:replace属性引入之前定义的copyright版权页面,示例代码如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<h1>Thymeleaf模板引擎</h1>
<h3>页面布局</h3>
<div th:insert="~{footer :: copyright}"></div>
</body>
</html>

在上面的示例中,在layout.html中通过th:insert引入先前定义的footer.html中的copyright代码片段,“~{footer :: copyright}”就是在当前模板页面引入的footer.html模板中的copyright片段。

步骤03 启动验证。

启动项目后,在浏览器中输入地址http://localhost:8080/layout,验证主页是否能正常引入footer.html代码片段,如图所示。

在这里插入图片描述
layout.html页面通过th:insert属性成功将footer页面的版权信息包含在主页中。

2.片段表达式语法规范

Thymeleaf片段表达式非常实用,可以实现模板页面的复用,避免相同内容需要修改多个页面的情况。

2.1 标记选择器

片段表达式的语法非常简单,其核心是标记选择器,由底层的AttoParser解析库定义,类似于XPath表达式或CSS选择器。片段表达式有以下3种不同的格式:

1)~{templatename::selector}:包含templatename和selector两个参数,其中templatename为页面模板的名称,selector为模板中定义的代码片段。例如上面示例中的“~{footer :: copyright}”就是在当前模板页面引入footer.html模板中的copyright片段。

2)~{templatename}:引入名为templatename的完整模板。

3)~{::selector}~{this::selector}:Thymeleaf支持从同一个模板插入一个片段,如果在当前的模板上找不到,将向最初处理的模板遍历,直到选择器匹配上对应的模板。

此外,标记选择器的模板名和选择器还可以包含条件判断或三目运算等其他表达式语法,比如:

<div th:insert="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div>

通过判断后台用户是否是管理员从而引入相应的代码片段,实现管理员和普通用户的页面区分。

2.2 引用普通的模板

标记选择器非常强大,可以包含不使用任何th:fragment属性的片段,甚至可以是来自完全不了解Thymeleaf的不同应用程序的标记代码:

    <div id="copy-section">&copy; 2023 The Thymeleaf footer</div>

我们可以使用上面的片段,只需通过它的id属性引用,类似于CSS选择器:

<div th:insert="~{footer :: #copy-section}"></div>

2.3 th:insert、th:replace和th:include的区别

th:insert、th:replace和th:include的功能基本类似,三者之间的差异如下:

  • th:insert是最简单的,它简单地插入指定的片段作为其宿主标签的主体。
  • th:replace实际上用指定的片段替换它的主机标签。
  • th:include与th:insert类似,但它并不插入片段,只插入该片段的内容。

3.可参数化片段

Thymeleaf支持在th:fragment定义的片段中指定一组参数,这使得模板片段更像一个可重复调用的函数。通过不同的参数控制模板的显示,从而达到模板共用的效果。

下面用th:fragment定义的片段指定一组参数:

    <div th:fragment="frag(onevar, twovar)"><p th:text="${onevar} + '-' + ${twovar}">...</p></div>

定义的frag片段包含两个参数,不需要定义参数的类型。

使用th:insert或th:replace调用此片段时,需要传入两个参数:

    <div th:replace="::frag (${value1},${value2})">...</div><div th:replace="::frag (onevar=${value1},twovar=${value2})">...</div>

片段的参数传递与函数调用类似,通过传入的参数控制页面显示。

实战:实现页面整体布局

一般业务处理系统页面整体布局基本上固定的。常用的框架模式将页面分为头部、左侧菜单栏、尾部和中间的展示区等页面。我们可以使用Thymeleaf的代码片段功能,实现应用系统页面整体布局。

下面通过示例演示Thymeleaf如何实现页面整体布局。

步骤01 在templates/layout目录下新建footer.html、header.html、left.html等各区域模板页面。

footer.html的内容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>footer</title>
</head>
<body><footer th:fragment="footer"><div style="position: fixed; bottom: 0px; background-color: green; width:100%"><h1 style="text-align:center">我是底部</h1></div></footer>
</body>
</html>

left.html的内容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>left</title>
</head>
<body>
<left th:fragment="left"><div style="background-color: red; width:200px;height: 80vh"><h1 style="margin: 0;">我是左侧</h1></div>
</left>
</body>
</html>

header.html的内容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>header</title>
</head>
<body>
<header th:fragment="header"><div style="background-color: blue; height: 100px"><h1 style="margin: 0;text-align: center;">我是头部</h1></div>
</header>
</body>
</html>

步骤02 在templates目录下新建index.html页面,内容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Layout</title>
</head>
<body style="margin: 0px;"><div th:replace="layout/header :: header"></div><div th:replace="layout/left :: left"></div><div th:replace="layout/footer :: footer"></div>
</body>
</html>

在上面的示例中,我们在index.html页面中使用th:replace的语法将网站的头部、尾部、左侧引入页面中。

步骤03 在后端添加访问入口。

    @RequestMapping("/index")public String index() {return "index";}

步骤04 运行验证。

前面3个步骤完成之后,启动后访问地址http://localhost:8080/layout/index,可以看到页面显示效果如图所示。

在这里插入图片描述

index.html页面已经成功地引入了页面的头部、尾部、左侧,实现了页面的整体布局。实际项目中以index.html为模板,任何页面使用此布局时,只需要替换中间的内容即可。

相关文章:

【Spring Boot】Thymeleaf模板引擎 — Thymeleaf页面布局

Thymeleaf页面布局 熟悉Thymeleaf的语法和表达式后&#xff0c;后面开发起来会更加得心应手。接下来好好研究一下Thymeleaf如何实现完整的Web系统页面布局。 1.引入代码片段 在模板中经常希望包含来自其他模板页面的内容&#xff0c;如页脚、页眉、菜单等。为了做到这一点&a…...

整理mongodb文档:删

个人博客 整理mongodb文档:删 求关注&#xff0c;哪儿不足&#xff0c;求大佬们指出&#xff0c;哪儿写的不够通俗易懂跟清晰&#xff0c;也求指出 文章概叙 本文主要是介绍了删除数据的几个方法&#xff0c;主要还是在介绍deleteMany、deleteOne以及remove&#xff0c;对于…...

篇二十三:设计模式的综合实例:构建完整项目

篇二十三&#xff1a;"设计模式的综合实例&#xff1a;构建完整项目" 开始本篇文章之前先推荐一个好用的学习工具&#xff0c;AIRIght&#xff0c;借助于AI助手工具&#xff0c;学习事半功倍。欢迎访问&#xff1a;http://airight.fun/。 另外有2本不错的关于设计模…...

FFmpeg常见命令行(三):FFmpeg转码

前言 在Android音视频开发中&#xff0c;网上知识点过于零碎&#xff0c;自学起来难度非常大&#xff0c;不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》。本文是Android音视频任务列表的其中一个&#xff0c; 对应的要学习的内容是&#xff1a;如何使…...

合宙Air724UG LuatOS-Air script lib API--scanCode

Table of Contents scanCode scanCode.request(cbFnc, timeout) scanCode 模块功能&#xff1a;扫码. 支持二维码、条形码扫描 scanCode.request(cbFnc, timeout) 设置扫码请求 参数 名称 传入值类型 释义 cbFnc function 扫码返回或者超时未返回的回调函数&#xff0c;回调…...

2023年新手如何学剪辑视频 想学视频剪辑如何入门

随着短视频、vlog等媒体形式的兴起&#xff0c;视频剪辑已经成为了热门技能。甚至有人说&#xff0c;不会修图可以&#xff0c;但不能不会剪视频。实际上&#xff0c;随着各种智能软件的发展&#xff0c;视频剪辑已经变得越来越简单。接下来&#xff0c;一起来看看新手如何学剪…...

C++的auto究竟是何方神圣

C的auto究竟是何方神圣 前言&#x1f64c;auto&#xff08;C 11&#xff09; 的使用细则auto是什么&#xff1f; auto声明的变量是在什么时期被编译器推导出来呢&#xff1f;为什么使用auto进行定义变量时&#xff0c;必须进行初始化&#xff1f; auto 的使用场景auto与指针和引…...

网络安全【黑客】面试题汇总

前言 一眨眼2023年已经过去一大半&#xff0c;不知道大家有没有找到心仪的工作。作为一个安全老鸟&#xff0c;工作这么多年&#xff0c;面试过很多人也出过很多面试题目&#xff0c;也在网上收集了各类关于渗透面试题目&#xff0c;里面有我对一些问题的见解&#xff0c;希望…...

docker菜谱大全

记录docker常用软件安装&#xff0c;感谢小马哥和杨师傅的投稿。&#x1f60e;&#x1f60e;&#x1f60e; 相关文档&#xff1a; DockerHub&#xff1a;https://hub.docker.com/Linux手册&#xff1a;https://linuxcool.com/Docker文档&#xff1a;https://docs.docker.com/Do…...

git: git checkout命令

git checkout 命令在Git中有不同的用法和功能&#xff0c;具体取决于您在命令后面提供的参数。以下是一些常见的用法&#xff1a; 1. 切换分支&#xff1a;您可以使用 git checkout <branch> 切换到指定的分支。例如&#xff0c;要切换到名为 "feature-branch"…...

以游戏编程的角度看待模拟时间的算法题——以PAT甲级1026 Table Tennis为例

对于需要模拟时间的算法题&#xff0c;可以将开始时间作为游戏的开始&#xff08;如Unity的Start或UE的BeginPlay&#xff09;&#xff0c;每一秒的模拟作为游戏的画面更新&#xff08;如Unity的Update或UE的Tick&#xff09;&#xff0c;结束时间可作为游戏的结束&#xff08;…...

SNAT与DNAT原理

SNAT和DNAT &#xff08;源地址转换和目标地址转换&#xff09; SNAT&#xff1a;源地址转换。内网到外网转换的是源地址。 DNAT&#xff1a;目标地址转换&#xff1a;外网到内网转换的是目的地址 &#xff08;把内部服务器的ip地址转换成一个所有人都可以访问的地址&#xff0…...

04-2_Qt 5.9 C++开发指南_SpinBox使用

文章目录 1. SpinBox简介2. SpinBox使用2.1 可视化UI设计2.2 widget.h2.3 widget.cpp 1. SpinBox简介 QSpinBox 用于整数的显示和输入&#xff0c;一般显示十进制数&#xff0c;也可以显示二进制、十六进制的数&#xff0c;而且可以在显示框中增加前缀或后缀。 QDoubleSpinBox…...

接口安全防护方案

文章目录 1.认证与授权机制2.参数校验3.接口加密4.防止暴力破解5.安全头设置6.日志监控 1.认证与授权机制 使用令牌&#xff08;Token&#xff09;、OAuth等认证方式&#xff0c;确保只有合法用户可以访问接口。授权机制可以防止未经授权的用户访问敏感接口。 示例&#xff1a;…...

机器学习复习题

1 单选题 ID3算法、C4.5算法、CART算法都是&#xff08; &#xff09;研究方向的算法。 A . 决策树 B. 随机森林 C. 人工神经网络 D. 贝叶斯学习 参考答案&#xff1a;A &#xff08; &#xff09;作为机器学习重要算法之一&#xff0c;是一种利用多个树分类器进行分类和预测…...

无线液位传感器—简介

近年来&#xff0c;随着无线传感网络技术的愈发成熟和稳定&#xff0c;无线传感器因其安装、维护方便&#xff0c;不用布线、节约成本&#xff0c;监测方便&#xff0c;使用灵活&#xff0c;可适用于多种工业领域等优点&#xff0c;正在逐步替代部分传统有线传感器&#xff0c;…...

通讯协议034——全网独有的OPC HDA知识一之聚合(三)时间加权平均

本文简单介绍OPC HDA规范的基本概念&#xff0c;更多通信资源请登录网信智汇(wangxinzhihui.com)。 本节旨在详细说明HDA聚合的要求和性能。其目的是使HDA聚合标准化&#xff0c;以便HDA客户端能够可靠地预测聚合计算的结果并理解其含义。如果用户需要聚合中的自定义功能&…...

Android 13 Hotseat定制化修改——003 hotseat图标大小修改

目录 一.背景 二.未修改前效果 三.修改后效果 一.背景 由于需求是需要自定义修改Hotseat,所以此篇文章是记录如何自定义修改hotseat的,应该可以覆盖大部分场景,修改点有修改hotseat布局方向,hotseat图标数量,hotseat图标大小,hotseat布局位置,hotseat图标禁止形成文件…...

21、springboot的宽松绑定及属性处理类的构造注入

springboot的宽松绑定及属性处理类的构造注入 ★ 如何使用属性处理类所读取的属性 属性处理类最终变成了Spring容器中的一个Bean组件&#xff0c;因此接下来Spring即可将该Bean组件注入任意其他组件。 这种做法的好处是&#xff1a;可以将大量的配置信息封装一个对象——所以…...

nginx负载均衡(反向代理)

nginx负载均衡 负载均衡&#xff1a;由反向代理来实现。 nginx的七层代理和四层代理&#xff1a; 七层是最常用的反向代理方式&#xff0c;只能配置在nginx配置文件的http模块当中&#xff0c;而且配置方法名称&#xff1a;upstream模块&#xff0c;不能写在server模块中&#…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

spring boot使用HttpServletResponse实现sse后端流式输出消息

1.以前只是看过SSE的相关文章&#xff0c;没有具体实践&#xff0c;这次接入AI大模型使用到了流式输出&#xff0c;涉及到给前端流式返回&#xff0c;所以记录一下。 2.resp要设置为text/event-stream resp.setContentType("text/event-stream"); resp.setCharacter…...

作为点的对象CenterNet论文阅读

摘要 检测器将图像中的物体表示为轴对齐的边界框。大多数成功的目标检测方法都会枚举几乎完整的潜在目标位置列表&#xff0c;并对每一个位置进行分类。这种做法既浪费又低效&#xff0c;并且需要额外的后处理。在本文中&#xff0c;我们采取了不同的方法。我们将物体建模为单…...

Spring事务传播机制有哪些?

导语&#xff1a; Spring事务传播机制是后端面试中的必考知识点&#xff0c;特别容易出现在“项目细节挖掘”阶段。面试官通过它来判断你是否真正理解事务控制的本质与异常传播机制。本文将从实战与源码角度出发&#xff0c;全面剖析Spring事务传播机制&#xff0c;帮助你答得有…...

基于谷歌ADK的 智能产品推荐系统(2): 模块功能详解

在我的上一篇博客&#xff1a;基于谷歌ADK的 智能产品推荐系统(1): 功能简介-CSDN博客 中我们介绍了个性化购物 Agent 项目&#xff0c;该项目展示了一个强大的框架&#xff0c;旨在模拟和实现在线购物环境中的智能导购。它不仅仅是一个简单的聊天机器人&#xff0c;更是一个集…...

[10-1]I2C通信协议 江协科技学习笔记(17个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17...