Thymeleaf3 中,支持了新的表达式~{ }
,这个表达式是专门用于处理片段(fragment)的,同时也可以用于选择当前文件内容中的片段(fragment),并且支持模板引入时一起调用,增加了很大的模板灵活性。
官方文档中的样例如下:
This allows us to create our fragments in a way such that they can be enriched with markup coming from the calling templates, resulting in a very flexible template layout mechanism.
Note the use of the
title
andlinks
variables in the fragment below:<head th:fragment="common_header(title,links)"> <title th:replace="${title}">The awesome applicationtitle> <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> <th:block th:replace="${links}" /> head>
We can now call this fragment like:
... <head th:replace="base :: common_header(~{::title},~{::link})"> <title>Awesome - Maintitle> <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"> <link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}"> head> ...
…and the result will use the actual
and
tags from our calling template as the values of the
title
andlinks
variables, resulting in our fragment being customized during insertion:
... <head> <title>Awesome - Maintitle> <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> ...
当时看到官方的使用样例后,理解到的是 ~{}
是将所有的 link标签和script标签内容都引用了,如果只需要部分的link和script 甚至是别的tag,是否可以做到呢?在亲自尝试了之后,发现了实现的办法。目前个人已经使用到的方式如下:
在一个base模板中可以定义一个项目中常用的head内容,例如 ,
,
等。
在满足全部页面的基础引用上,往往有个别页面需要引入额外的css或者js脚本内容。有了表达式~{}
之后,就方便多了,如下写:
base.html:
<head th:fragment="commonHeader(title,links,scripts)">
<title th:replace="${title}">titletitle>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" th:href="@{/asserts/css/page.css}" href="../static/asserts/css/page.css" type="text/css"
media="screen, projection"/>
<script type="text/javascript" th:src="@{/asserts/js/jquery-1.8.2.min.js}" src="../static/asserts/js/jquery-1.8.2.min.js">script>
<th:block th:replace="${links}" />
<th:block th:replace="${scripts}" />
head>
main.html:
<head th:replace="base::commonHeader(~{::title},~{::links},~{::scripts})">
<title>maintitle>
<th:block th:fragment="links">
<link rel="stylesheet" href="../static/asserts/css/screen.css"
th:href="@{/asserts/css/screen.css}" type="text/css"
media="screen, projection" />
th:block>
<th:block th:fragment="scripts">
<script language="JavaScript">
function fun() {
...
}
script>
th:block>
<script type="text/javascript"
src="../static/asserts/js/jquery-1.8.2.min.js">script>
head>
在Thymeleaf3渲染之后得到如下结果:
<head>
<title>maintitle>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" href="/asserts/css/page.css" type="text/css"
media="screen, projection"/>
<script type="text/javascript" src="/asserts/js/jquery-1.8.2.min.js">script>
<link rel="stylesheet" href="/asserts/css/screen.css"
type="text/css"
media="screen, projection" />
<script language="JavaScript">
function fun() {
...
}
script>
head>
如果不需要额外的引入 css 或者 js,则可以这么传递参数:
<head th:replace="base::commonHeader(_,_,_)">
head>
在使用的基础上,还可以将常规将常规的界面整个文件作为模板,将个别内容使用
进行替换。例如,将一个查询界面连同样式均作为模板,其中的 查询条件区域 , 结果展示区域 之外的内容均可以固定下来,然后按照需要将查询条件、结果展示区域嵌入:
queryBase.html
<form id="form" action="javascript:void(0)" th:action="@{/queryDemo}" method="post" name="form">
<th:block th:fragment="main(query,result)">
<div class="userbox">
<div> <b class="b1">b> <b class="b2">b>
<b class="b3">b>
<b class="b4">b>
<div class="contentb">
<th:block th:replace="${query}">
等待替换
th:block>
div>
<b class="b4">b>
<b class="b3">b>
<b class="b2">b>
<b class="b1">b>
div>
div>
<div class="tablebox" style="overflow:visible;">
<th:block th:replace="${result}">
等待替换
th:block>
<br/>
<br/>
<div class="table_navi" th:fragment="pageBar">
......
div>
div>
th:block>
form>
在具体的查询界面
queryList.html
<form id="form" action="javascript:void(0)" th:action="@{/queryDemo}" method="post" name="form">
<th:block th:replace="queryBase::main(~{::queryArea},~{::resultArea})">
<table th:fragment="queryArea"
border="0" cellspacing="3" cellpadding="0" class="content_table">
<tr>
<td width="120" height="30" align="right">
日期:
td>
<td>
td>
....省略....
tr>
<tr>
<td height="30" colspan="15" align="right">
<input type="submit" value="查询" class="inp_L3" />
td>
tr>
table>
<table th:fragment="resultArea" width="100%" border="0" cellspacing="0" cellpadding="0">
<tr class="titlebg">
<td align="center" nowrap="nowrap" class="titlebg">
全选<input type="checkbox" id="mainBox"/>
td>
<td align="center" nowrap="nowrap" class="titlebg">
日期
td>
....省略....
tr>
<tr th:if="${orderVoList}" th:each="order,stat:${orderVoList}">
<td align="center" nowrap="nowrap" >
<input type="checkbox" name="objId" th:id="objId+${stat.count}" th:value="${order.id}" value="testId" />
<input type="hidden" name="objStatus" th:value="${order.status}"/>
td>
<td align="center" nowrap="nowrap"
th:text="${#calendars.format(order.createTime,'yyyy-MM-dd')}">
2018-01-01
td>
....省略....
tr>
table>
th:block>