深色模式
8.3 灵活的布局:超越单纯的片段插入
借助片段表达式的强大能力,我们可以给模板片段传递「非文本/数字/对象类型」的参数——具体来说,是传递标记片段(markup fragments)。
这种方式能让我们设计出可被「动态增强」的通用片段:调用模板可以传入自定义的标记内容,片段会将这些内容融合到自身结构中,最终实现高度灵活的模板布局机制。
注意看下面这个片段,它接收 title 和 links 两个参数(类型为标记片段),并将其嵌入到自身结构中:
html
<!-- base.html 中的通用头部片段 -->
<head th:fragment="common_header(title,links)">
<!-- 替换为传入的 title 标记片段 -->
<title th:replace="${title}">The awesome application</title>
<!-- 通用样式/脚本(所有页面共享) -->
<link rel="stylesheet" type="text/css" media="all" th:href="@{/css/awesomeapp.css}">
<link rel="shortcut icon" th:href="@{/images/favicon.ico}">
<script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"></script>
<!-- 每页自定义链接的占位符:替换为传入的 links 标记片段 -->
<th:block th:replace="${links}" />
</head>在业务页面中调用 common_header,并传入当前页面的 <title> 和 <link> 作为标记片段参数:
html
<!-- 业务页面的头部:调用通用片段并传递自定义标记 -->
<head th:replace="~{ base :: common_header(~{::title},~{::link}) }">
<!-- 自定义标题:会作为 title 参数传入片段 -->
<title>Awesome - Main</title>
<!-- 自定义样式链接:会作为 links 参数传入片段 -->
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}">
</head>~{::title}:选取当前模板中<title>标签的标记片段,作为title参数;~{::link}:选取当前模板中所有<link>标签的标记片段,作为links参数;- 调用时将这两个标记片段传递给
common_header,实现通用片段的动态定制。
通用片段会融合传入的自定义标记,生成既包含通用内容、又有页面自定义内容的头部:
html
<head>
<!-- 来自调用模板的自定义标题 -->
<title>Awesome - Main</title>
<!-- 通用样式/脚本(片段自带) -->
<link rel="stylesheet" type="text/css" media="all" href="/awe/css/awesomeapp.css">
<link rel="shortcut icon" href="/awe/images/favicon.ico">
<script type="text/javascript" src="/awe/sh/scripts/codebase.js"></script>
<!-- 来自调用模板的自定义样式链接 -->
<link rel="stylesheet" href="/awe/css/bootstrap.min.css">
<link rel="stylesheet" href="/awe/themes/smoothness/jquery-ui.css">
</head>核心优势与扩展说明
- 布局复用+个性化:通用片段保留所有页面的公共内容(如基础样式、脚本),同时通过标记参数接收页面自定义内容,兼顾复用性和灵活性;
th:block的价值:用于承载「无实体标签的替换逻辑」,避免生成多余的<div>/<span>等标签,保持 HTML 结构简洁;- 更灵活的传参方式:可传递任意标记片段(如
<script>、<meta>等),甚至是带条件判断的动态标记:html<!-- 传入带条件的自定义脚本片段 --> <head th:replace="~{ base :: common_header( ~{::title}, ~{::link}, ~{<th:block th:if="${user.isAdmin}"><script th:src="@{/js/admin.js}"></script></th:block>} ) }"> ... </head> - 简化写法:可省略片段表达式的
~{},简写为:html<head th:replace="base :: common_header(::title,::link)"> ... </head>
总结
- 片段表达式支持传递「标记片段」作为参数,让通用片段可接收调用模板的自定义标记;
- 核心思路是「通用结构+自定义内容」:通用片段封装公共布局,调用模板传入页面专属标记;
th:block是实现无冗余布局的关键,可承载标记替换逻辑而不生成额外标签。
