# Thymeleaf模板 页面布局(Page Layouts)

xiaoxiao2021-03-01  8

Thymeleaf模板 页面布局(Page Layouts)

官方文档地址

Thymeleaf标准布局系统

1.基础的

让我们简短的分析下包含语句:

<div th:replace="fragments/header :: header">...</div>

fragments/header 即为 fragments/header.html是我们正在引用的模板文件的名称,双冒号后面的表达式header是一个 fragment 选择器 。

文件 :fragments/header.html

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> ... </head> <body> <!--在这里指定 fragment --> <div th:fragment="header1"> <p>我是header1</p> </div> ... <div th:fragment="header2"> <p>我是header2</p> </div> </body>

然后在其他HTML中:

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> ... </head> <body> ... <!--引用 th:fragment="header1"--> <div th:replace="fragments/header :: header1">...<div> </body>

就把第一个 div 引用过来了,通过这种方式,我们可以在一个模板文件中定义多个片段,就像上面做的那样。

这里重要的是,所有的模板仍然可以是自然模板,并且可以在没有运行服务器的浏览器中查看。


2.通过标记选择器

通过使用标记选择器语法,类似 jQuery 选择器,thymeleaf 可以选择任意部分作为片段,而不用事先标记。 标记选择器语法地址

<div th:insert="https://www.thymeleaf.org :: div.description" >...</div>

上面的代码将包含一个来自thymeleaf.org 的 class=“description” 的 div 。

为了实现这一点,模板引擎必须配置为 UrlTemplateResolver 如下:

@Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.addTemplateResolver(new UrlTemplateResolver()); ... return templateEngine; }

3.使用表达式

在 templatename :: selector中, templatename 和selector都可以是表达式。

<div th:replace="fragments/header:: ${#authentication.isAdmin()} ? 'header1' : 'header2'"> © 2016 The Static Templates </div>

4.带参数的

显式定义:

<!--在这里定义带参数的 th:fragment="alert (type, message)"--> <div th:fragment="alert (type, message)" th:assert="${!#strings.isEmpty(type) and !#strings.isEmpty(message)}" class="alert alert-dismissable" th:classappend="'alert-' + ${type}"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> <span th:text="${message}">Test</span> </div>

其他页面使用的时候传递参数给它:

<th:block th:if="${message != null}"> <div th:replace="fragments/alert :: alert (type=${#strings.toLowerCase(message.type)}, message=#{${message.message}(${#authentication.name})})"> </div> </th:block>

5.Fragment 表达式

Thymeleaf 3.0 新增方式 task/layout.html页面:

<head th:fragment="head(title, links, scripts)"> <title th:replace="${title}">Task List</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <link href="../../../resources/css/bootstrap.min.css" rel="stylesheet" media="screen" th:href="@{/resources/css/bootstrap.min.css}"/> <link href="../../../resources/css/core.css" rel="stylesheet" media="screen" th:href="@{/resources/css/core.css}"/> <!--/* Per-page placeholder for additional links */--> <th:block th:replace="${links}" /> <!--/* Per-page placeholder for additional scripts */--> <th:block th:replace="${scripts}" />

其他页面:

<head th:replace="task/layout :: head(~{this :: title}, ~{this :: .custom-link}, ~{this :: .custom-script})"> <title>Task Details</title> <!-- 这块相同的就是`task/layout`页面共有的 --> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <link href="../../../resources/css/bootstrap.min.css" rel="stylesheet" media="screen" th:href="@{/resources/css/bootstrap.min.css}"/> <link href="../../../resources/css/core.css" rel="stylesheet" media="screen" th:href="@{/resources/css/core.css}"/> <!-- Custom links for this page only --> <link class="custom-link" href="../../../resources/css/task/task.css" th:href="@{/resources/css/task/task.css}" /> <!-- Custom scripts for this page only --> <script class="custom-script" src="../../../resources/js/task/task.js" th:src="@{/resources/js/task/task.js}"></script> </head>

1.这个表达式灵活的地方就在于既拿到了模板页面的东西,又在模板页面的基础上添加了自己独有的东西。 2.单独打开task/layout.html页面会报错。

来自Spring @Controller的 fragment

页面点击注册按钮弹出模态框:

<script th:inline="javascript" type="text/javascript"> /* Fill in modal with content loaded with Ajax */ $(document).ready(function () { $('#signup').on('click', function (e) { $("#myModal").modal(); $("#myModalBody").text(""); $.ajax({ url: "signup", cache: false }).done(function (html) { $("#myModalBody").append(html); }); }) }); </script> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title" id="myModalLabel">Signup</h4> </div> <div class="modal-body" id="myModalBody">Lorem ipsum</div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal -->

可以看出上面的模态框内容是空白的,显示的内容是由ajax返回的数据。

在 signup/signup.html定义返回的 html (th:fragment="signupForm"):

<!DOCTYPE html> <html> <head> ... </head> <body> <form method="post" th:action="@{/signup}" th:object="${signupForm}" th:fragment="signupForm"> ... </form> </body> </html>

在Controller中返回的字符串为 signup/signup :: signupForm指向了上面这个

private static final String SIGNUP_VIEW_NAME = "signup/signup"; @RequestMapping(value = "signup") public String signup(Model model, @RequestHeader("X-Requested-With") String requestedWith) { model.addAttribute(new SignupForm()); if (AjaxUtils.isAjaxRequest(requestedWith)) { return SIGNUP_VIEW_NAME.concat(" :: signupForm"); } return SIGNUP_VIEW_NAME; }

效果查看需要在服务器上运行(官网说这个 Thymol 可以在不运行的时候查看 有时间再看吧)

Thymeleaf Layout Dialect

1.配置

<dependency> <groupId>nz.net.ultraq.thymeleaf</groupId> <artifactId>thymeleaf-layout-dialect</artifactId> <version>2.0.5</version> </dependency>

我们还需要通过在模板引擎中添加额外的配置:

@Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); ... templateEngine.addDialect(new LayoutDialect()); return templateEngine; }

2.创建一个布局

task-ld/layout.html创建layout:fragment="content"

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"> <head>...</head> <body> <div th:replace="fragments/header :: header"></div> <div class="container"> <!--在这里设置layout布局--> <div layout:fragment="content">...</div> <div th:replace="fragments/footer :: footer">© 2017 The Static Templates</div> </div> </body> </html>

在task-ld/task-list.html页面引用:

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{task-ld/layout}"> <head></head> <body> <div layout:fragment="content">...</div> </body> </html>

注意<html>元素中的layout:decorate="~{task-ld/layout}" task-list.html中的layout:fragment="content"会替换 layout.html中的。其他东西继承过来。比如头尾。

task-list.html页面没有layout布局的时候: task-list.html页面有layout布局的时候:可以看出多了 头和尾

Include style approach with Layout Dialect

task-ld/alert.html页面设置layout:fragment

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"> <body> <th:block layout:fragment="alert"> <div class="alert alert-dismissable" th:classappend="'alert-' + ${type}"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> <h4 th:text="${header}">Alert header</h4> <!--/* 'layout:fragment' attribute defines a replaceable content section */--> <th:block layout:fragment="alert-content"> <p>Default alert content</p> </th:block> </div> </th:block> </body> </html>

在task-ld/task-list.html页面调用:

<div layout:insert="~{task-ld/alert :: alert}" th:with="type='info', header='Info'" th:remove="tag"> <!--/* Implements alert content fragment with simple content */--> <th:block layout:fragment="alert-content"> <p><em>This is a simple list of tasks!</em></p> </th:block> </div>

或者:

<div layout:insert="~{task-ld/alert :: alert}" th:with="type='danger', header='Oh snap! You got an error!'" th:remove="tag"> <!--/* Implements alert content fragment with full-blown HTML content */--> <th:block layout:fragment="alert-content"> <p>Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras mattis consectetur purus sit amet fermentum.</p> <p> <button type="button" class="btn btn-danger">Take this action</button> <button type="button" class="btn btn-default">Or do this</button> </p> </th:block> </div>

还是看这幅图,样式都调用到了,内容做了替换。

关于thymeleaf th:replace th:include th:insert 的区别

th:insert :保留自己的主标签,保留th:fragment的主标签。 th:replace :不要自己的主标签,保留th:fragment的主标签。 th:include :保留自己的主标签,不要th:fragment的主标签。(官方3.0后不推荐)

这是第一篇博客,看的是tylmeleaf布局相关,后面继续看Thymeleaf的文档。ヾ(◍°∇°◍)ノ゙加油。

转载请注明原文地址: https://www.6miu.com/read-3100253.html

最新回复(0)