@lirenmi
2017-08-12T09:19:08.000000Z
字数 19671
阅读 578
thymeleaf
<html xmlns:th="http://www.thymeleaf.org">
html 头部
<p data-th-text="#{home.welcome}">Welcome to our grocery store!</p>
data-th-text
<p th:utext="#{home.welcome}">Welcome to our grocery store!</p>
非转义
<body>
<p th:utext="#{home.welcome}">Welcome to our grocery store!</p>
<p>Today is: <span th:text="${today}">13 February 2011</span></p>
</body>
#{...}表示特定值,${...}表示变量
简单表达式:
${...}
*{...}
#{...}
@{...}
~{...}
字面
'one text'
,'Another one!'
,...0
,34
,3.0
,12.3
,...true
,false
null
one
,sometext
,main
,...文本操作:
+
|The name is ${name}|
算术运算:
+
,-
,*
,/
,%
-
布尔操作:
and
,or
!
,not
比较和平等:
>
,<
,>=
,<=
(gt
,lt
,ge
,le
)==
,!=
(eq
,ne
)条件判断:
(if) ? (then)
(if) ? (then) : (else)
(value) ?: (defaultvalue)
特殊记号:
_
所有这些功能都可以组合和嵌套
'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))
<p th:utext="#{home.welcome(${session.user.name})}">
Welcome to our grocery store, Sebastian Pepper!
</p>
可以传参数
取值:
/*
* . 对象取值一
*/
${person.father.name}
/*
* 对象取值二
*/
${person['father']['name']}
/*
* map
*/
${countriesByCode.ES}
${personsByName['Stephen Zucchini'].age}
/*
* 集合取值
*/
${personsArray[0].name}
/*
* 调用方法,可以用参数
*/
${person.createCompleteName()}
${person.createCompleteNameWithSeparator('-')}
基本对象:
#ctx
:上下文对象。#vars:
内容变量。#locale
:上下文的语言环境。#request
:(只在网页上下文)的HttpServletRequest
对象。#response
:(只在网页上下文)的HttpServletResponse
对象。#session
:(只在网页上下文)的HttpSession
对象。#servletContext
:(只在网页上下文)的ServletContext
对象。例如:
<span th:text="${#locale.country}">US</span>.
功能对象:
#execInfo
:正在处理有关模板的信息。#messages
:获得外在信息内部变量表达式,以同样的方式,因为他们将使用#{...}语法来获得的方法。#uris
:方法逸出的URL / URI的零件#conversions
:用于执行所述配置的方法转换服务(如果有的话)。#dates
:方法java.util.Date
对象:格式化,分量提取等#calendars
:类似#dates
,但java.util.Calendar
对象。#numbers
:方法格式化数字对象。#strings
:用于方法String
对象:contains, startsWith, prepending/appending, etc.#objects
:对一般对象的方法。#bools
:布尔评价方法。#arrays
:用于阵列的方法。#lists
:对列表的方法。#sets
:为集的方法。#maps
:对于地图的方法。#aggregates
:用于创建关于阵列或集合的聚集体的方法。#ids
:方法与可能被重复的id属性处理(例如,作为迭代的结果)。例如:
<p>
Today is: <span th:text="${#calendars.format(today,'dd MMMM yyyy')}">13 May 2011</span>
</p>
选择对象:th:object
<div th:object="${session.user}">
<p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
</div>
等价于:
<div>
<p>Name: <span th:text="${session.user.firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="${session.user.nationality}">Saturn</span>.</p>
</div>
*
和$
混用:
<div th:object="${session.user}">
<p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
</div>
当一个对象的选择是在适当位置,所选择的对象也将提供给元表达式作为#object
表达变量:
<div th:object="${session.user}">
<p>Name: <span th:text="${#object.firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
</div>
至于说,如果没有对象的选择已经完成,美元和星号语法是等价的
<div>
<p>Name: <span th:text="*{session.user.name}">Sebastian</span>.</p>
<p>Surname: <span th:text="*{session.user.surname}">Pepper</span>.</p>
<p>Nationality: <span th:text="*{session.user.nationality}">Saturn</span>.</p>
</div>
<p>Please select an option</p>
<ol>
<li><a href="product/list.html" th:href="@{/product/list}">Product List</a></li>
<li><a href="order/list.html" th:href="@{/order/list}">Order List</a></li>
<li><a href="subscribe.html" th:href="@{/subscribe}">Subscribe to our Newsletter</a></li>
<li><a href="userprofile.html" th:href="@{/userprofile}">See User Profile</a></li>
</ol>
<!-- Will produce 'http://localhost:8080/gtvg/order/details?orderId=3' (plus rewriting) -->
<a href="details.html"
th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">view</a>
<!-- Will produce '/gtvg/order/details?orderId=3' (plus rewriting) -->
<a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a>
<!-- Will produce '/gtvg/order/3/details' (plus rewriting) -->
<a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>
<a th:href="@{${url}(orderId=${o.id})}">view</a>
<a th:href="@{'/details/'+${user.login}(orderId=${o.id})}">view</a>
文本:
<p>
Now you are looking at a <span th:text="'working web application'">template file</span>.
</p>
文本文字是单引号之间仅指定字符串,避免使用 ‘
数字:
<p>The year is <span th:text="2013">1492</span>.</p>
<p>In two years, it will be <span th:text="2013 + 2">1494</span>.</p>
布尔:
<div th:if="${user.isAdmin()} == false"> ...
or
<div th:if="${user.isAdmin() == false}"> ...
null:
<div th:if="${variable.something} == null"> ...
文字标记:
<div th:class="content">...</div>
代替:
<div th:class="'content'">...</div>
<span th:text="'The name of the user is ' + ${user.name}">
<span th:text="|Welcome to our application, ${user.name}!|">
相当于:
<span th:text="'Welcome to our application, ' + ${user.name} + '!'">
组合:
<span th:text="${onevar} + ' ' + |${twovar}, ${threevar}|">
|...|
内部只允许${...}
,*{...}
,#{...}
<div th:with="isEven=(${prodStat.count} % 2 == 0)">
OGNL
<div th:with="isEven=${prodStat.count % 2 == 0}">
<div th:if="${prodStat.count} > 1">
<span th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')">
别名:
gt
(>
), (lt
),<
( ),ge
(),>=
()。 另外(),/ ()。le``<=``not``!``eq``==``neq``ne``!=
<tr th:class="${row.even}? 'even' : 'odd'">
...
</tr>
嵌套:
<tr th:class="${row.even}? (${row.first}? 'first' : 'even') : 'odd'">
...
</tr>
省略:
<tr th:class="${row.even}? 'alt'">
...
</tr>
<div th:object="${session.user}">
...
<p>Age: <span th:text="*{age}?: '(no age specified)'">27</span>.</p>
</div>
等同于:
<p>Age: <span th:text="*{age != null}? *{age} : '(no age specified)'">27</span>.</p>
括号内嵌套表达式:
<p>
Name:
<span th:text="*{firstName}?: (*{admin}? 'Admin' : #{default.username})">Sebastian</span>
</p>
<span th:text="${user.name} ?: _">no user authenticated</span>
等同
<span th:text="${user.name} ?: 'no user authenticated'">...</span>
<p th:text="${__#{article.text('textVar')}__}">Some text here...</p>
等价于
<p th:text="${@myapp.translator.Translator@translateToFrench(textVar)}">Some text here...</p>
<td th:text="${{user.lastAccessDate}}">...</td>
${{...}}
转换为Calendar -> String
th:attr
属性设置任何属性的值
<form action="subscribe.html" th:attr="action=@{/subscribe}">
<fieldset>
<input type="text" name="email" />
<input type="submit" value="Subscribe!" th:attr="value=#{subscribe.submit}"/>
</fieldset>
</form>
多个属性:
<img src="../../images/gtvglogo.png"
th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />
输出:
<img src="/gtgv/images/gtvglogo.png" title="Logo de Good Thymes" alt="Logo de Good Thymes" />
设置value
属性,使用th:value
:
<input type="submit" value="Subscribe!" th:value="#{subscribe.submit}"/>
action
<form action="subscribe.html" th:action="@{/subscribe}">
href:
<li><a href="product/list.html" th:href="@{/product/list}">Product List</a></li>
各个html5的值
th:abbr |
th:accept |
th:accept-charset |
---|---|---|
th:accesskey |
th:action |
th:align |
th:alt |
th:archive |
th:audio |
th:autocomplete |
th:axis |
th:background |
th:bgcolor |
th:border |
th:cellpadding |
th:cellspacing |
th:challenge |
th:charset |
th:cite |
th:class |
th:classid |
th:codebase |
th:codetype |
th:cols |
th:colspan |
th:compact |
th:content |
th:contenteditable |
th:contextmenu |
th:data |
th:datetime |
th:dir |
th:draggable |
th:dropzone |
th:enctype |
th:for |
th:form |
th:formaction |
th:formenctype |
th:formmethod |
th:formtarget |
th:fragment |
th:frame |
th:frameborder |
th:headers |
th:height |
th:high |
th:href |
th:hreflang |
th:hspace |
th:http-equiv |
th:icon |
th:id |
th:inline |
th:keytype |
th:kind |
th:label |
th:lang |
th:list |
th:longdesc |
th:low |
th:manifest |
th:marginheight |
th:marginwidth |
th:max |
th:maxlength |
th:media |
th:method |
th:min |
th:name |
th:onabort |
th:onafterprint |
th:onbeforeprint |
th:onbeforeunload |
th:onblur |
th:oncanplay |
th:oncanplaythrough |
th:onchange |
th:onclick |
th:oncontextmenu |
th:ondblclick |
th:ondrag |
th:ondragend |
th:ondragenter |
th:ondragleave |
th:ondragover |
th:ondragstart |
th:ondrop |
th:ondurationchange |
th:onemptied |
th:onended |
th:onerror |
th:onfocus |
th:onformchange |
th:onforminput |
th:onhashchange |
th:oninput |
th:oninvalid |
th:onkeydown |
th:onkeypress |
th:onkeyup |
th:onload |
th:onloadeddata |
th:onloadedmetadata |
th:onloadstart |
th:onmessage |
th:onmousedown |
th:onmousemove |
th:onmouseout |
th:onmouseover |
th:onmouseup |
th:onmousewheel |
th:onoffline |
th:ononline |
th:onpause |
th:onplay |
th:onplaying |
th:onpopstate |
th:onprogress |
th:onratechange |
th:onreadystatechange |
th:onredo |
th:onreset |
th:onresize |
th:onscroll |
th:onseeked |
th:onseeking |
th:onselect |
th:onshow |
th:onstalled |
th:onstorage |
th:onsubmit |
th:onsuspend |
th:ontimeupdate |
th:onundo |
th:onunload |
th:onvolumechange |
th:onwaiting |
th:optimum |
th:pattern |
th:placeholder |
th:poster |
th:preload |
th:radiogroup |
th:rel |
th:rev |
th:rows |
th:rowspan |
th:rules |
th:sandbox |
th:scheme |
th:scope |
th:scrolling |
th:size |
th:sizes |
th:span |
th:spellcheck |
th:src |
th:srclang |
th:standby |
th:start |
th:step |
th:style |
th:summary |
th:tabindex |
th:target |
th:title |
th:type |
th:usemap |
th:value |
th:valuetype |
th:vspace |
th:width |
th:wrap |
th:xmlbase |
th:xmllang |
th:xmlspace |
<img src="../../images/gtvglogo.png"
th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />
or
<img src="../../images/gtvglogo.png"
th:src="@{/images/gtvglogo.png}" th:title="#{logo}" th:alt="#{logo}" />
or
<img src="../../images/gtvglogo.png"
th:src="@{/images/gtvglogo.png}" th:alt-title="#{logo}" />
th:attrappend
和th:attrprepend
属性
<input type="button" value="Do it!" class="btn" th:attrappend="class=${' ' + cssStyle}" />
cssStyle
设置为变量"warning"
,你会得到:
<input type="button" value="Do it!" class="btn warning" />
th:classappend
和th:styleappend
属性专门用于添加CSS类和style样式:
<tr th:each="prod : ${prods}" class="row" th:classappend="${prodStat.odd}? 'odd'">
例如checked
:
<input type="checkbox" name="active" th:checked="${user.active}" />
固定值布尔属性
th:async |
th:autofocus |
th:autoplay |
---|---|---|
th:checked |
th:controls |
th:declare |
th:default |
th:defer |
th:disabled |
th:formnovalidate |
th:hidden |
th:ismap |
th:loop |
th:multiple |
th:novalidate |
th:nowrap |
th:open |
th:pubdate |
th:readonly |
th:required |
th:reversed |
th:scoped |
th:seamless |
th:selected |
<span th:whatever="${user.name}">...</span>
导致:
<span whatever="John Apricot">...</span>
<table>
<tr data-th-each="user : ${users}">
<td data-th-text="${user.login}">...</td>
<td data-th-text="${user.name}">...</td>
</tr>
</table>
th:each
属性:
<tr th:each="prod : ${prods}">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
可迭代值:
java.util.Iterable
对象java.util.Enumeration
。java.util.Iterator
java.util.Map
Array
index
属性。count
属性。size
属性。current
属性。even/odd
布尔属性。first
布尔属性。last
布尔属性。状态变量:iterStat
<tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
如果你没有明确设置状态变量,Thymeleaf总是会被后面添加为您创建一个Stat
到迭代变量的名称:
<tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
th:if`属性:
<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:if="${not #lists.isEmpty(prod.comments)}">view</a>
true
.th:if
逆属性th:unless
:
<a href="comments.html"
th:href="@{/comments(prodId=${prod.id})}"
th:unless="${#lists.isEmpty(prod.comments)}">view</a>
th:switch
/ th:case
属性
<div th:switch="${user.role}">
<p th:case="'admin'">User is an administrator</p>
<p th:case="#{roles.manager}">User is a manager</p>
<p th:case="*">User is some other thing</p>
</div>
默认选项被指定为
th:case="*"
定义和引用片段:
定义片段:th:fragment
属性
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</div>
</body>
</html>
引用片段copy
,使用th:insert
或th:replace
属性
<body>
...
<div th:insert="~{footer :: copy}"></div>
</body>
or
<body>
...
<div th:insert="footer :: copy"></div>
</body>
选择条件
<div th:insert="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div>
不使用th:fragment
引入:
...
<div id="copy-section">
© 2011 The Good Thymes Virtual Grocery
</div>
...
使用id
属性引入
<body>
...
<div th:insert="~{footer :: #copy-section}"></div>
</body>
th:insert
和th:replace
之间的区别
th:insert
是最简单的:它会简单地插入指定的片断作为它的主机标记的主体。th:replace
实际上取代了与指定的片段其主机标签。th:include
类似于th:insert
,但而不是将其插入只插入片段内容本片段。(3.0不推荐使用)例如
定义:
<footer th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</footer>
引用:
<body>
...
<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div>
</body>
结果:
<body>
...
<div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
<div>
© 2011 The Good Thymes Virtual Grocery
</div>
</body>
定义:
<div th:fragment="frag (onevar,twovar)">
<p th:text="${onevar} + ' - ' + ${twovar}">...</p>
</div>
引用:二选一
<div th:replace="::frag (${value1},${value2})">...</div>
<div th:replace="::frag (onevar=${value1},twovar=${value2})">...</div>
or:
<div th:replace="::frag (twovar=${value2},onevar=${value1})">...</div>
不带片段参数的片段局部变量
即使没有定义参数:
<div th:fragment="frag">
...
</div>
可以使用上面指定的第二个语法来调用它们(只有第二个语法):
<div th:replace="::frag (onevar=${value1},twovar=${value2})">
这将相当于组合th:replace
和th:with
:
<div th:replace="::frag" th:with="onevar=${value1},twovar=${value2}">
th:assert
断言
<div th:assert="${onevar},(${twovar} != 43)">...</div>
这有助于验证片段签名中的参数:
<header th:fragment="contentheader(title)" th:assert="${!#strings.isEmpty(title)}">...</header>
定义
<head th:fragment="common_header(title,links)">
<title th:replace="${title}">The awesome application</title>
<!-- Common styles and scripts -->
<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>
<!--/* Per-page placeholder for additional links */-->
<th:block th:replace="${links}" />
</head>
引入:
...
<head th:replace="base :: common_header(~{::title},~{::link})">
<title>Awesome - Main</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}">
</head>
...
结果:
...
<head>
<title>Awesome - Main</title>
<!-- Common styles and scripts -->
<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>
...
使用空片段
一个特殊的片段表达式,空的fragment()可以用来指定没有标记。
<head th:replace="base :: common_header(~{::title},~{})">
<title>Awesome - Main</title>
</head>
...
注意如何片段的(第二个参数links
)被设定为空的片段,并且因此没有被用于写入的<th:block th:replace="${links}" />
块:
...
<head>
<title>Awesome - Main</title>
<!-- Common styles and scripts -->
<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>
</head>
...
如果我们只想让我们的片段将其当前标记用作默认值,那么no-op也可以用作片段的参数。
...
<head th:replace="base :: common_header(_,~{::link})">
<title>Awesome - Main</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}">
</head>
...
看看参数(片段的第一个参数)如何设置为no-op(),这导致片段的这部分不被执行(= no-operation):
<title th:replace="${title}">The awesome application</title>
结果:
...
<head>
<title>The awesome application</title>
<!-- Common styles and scripts -->
<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>
...
高级条件插入片段
例如,我们可以这样做,以便仅当用户是管理员时插入我们的片段,并且不插入(emtpy片段)(如果不是)
...
<div th:insert="${user.isAdmin()} ? ~{common :: adminhead} : ~{}">...</div>
...
另外,只有满足指定的条件,我们才可以使用无操作令牌来插入片段,但是如果不满足条件,则不需要修改则保留标记:
...
<div th:insert="${user.isAdmin()} ? ~{common :: adminhead} : _">
Welcome [[${user.name}]], click <a th:href="@{/support}">here</a> for help-desk support.
</div>
...
另外,如果我们配置了我们的模板解析器来检查模板资源的存在(通过它们的标志),我们可以使用片段本身的存在作为默认操作中的条件:
...
<!-- The body of the <div> will be used if the "common :: salutation" fragment -->
<!-- does not exist (or is empty). -->
<div th:insert="~{common :: salutation} ?: _">
Welcome [[${user.name}]], click <a th:href="@{/support}">here</a> for help-desk support.
</div>
...
<tr class="odd" th:remove="all">
<td>Blue Lettuce</td>
<td>9.55</td>
<td>no</td>
<td>
<span>0</span> comment/s
</td>
</tr>
all
:同时删除包含标签及其所有子项。body
:不要删除含有标记,但删除其所有的孩子。tag
:删除包含标记,但不删除其孩子。all-but-first
:删除包含标记的所有孩子除了第一个。none
: 没做什么。该值是动态评估有用。
<a href="/something" th:remove="${condition}? tag : none">Link text not to be removed</a>
<a href="/something" th:remove="${condition}? tag">Link text not to be removed</a>
<tr>
里面有效
<tr th:each="prod : ${prods}">
...
</tr>
th:with
属,下面实例中变量,比如firstPer
和secondPer
只在<div>
内部有效
<div th:with="firstPer=${persons[0]}">
<p>
The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.
</p>
</div>
<div th:with="firstPer=${persons[0]},secondPer=${persons[1]}">
<p>
The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.
</p>
<p>
But the name of the second person is
<span th:text="${secondPer.name}">Marcus Antonius</span>.
</p>
</div>
<div th:with="company=${user.company + ' Co.'},account=${accounts[company]}">...</div>
<p th:with="df=#{date.format}">
Today is: <span th:text="${#calendars.format(today,df)}">13 February 2011</span>
</p>
<p>
Today is:
<span th:with="df=#{date.format}"
th:text="${#calendars.format(today,df)}">13 February 2011</span>
</p>
<ul>
<li th:each="item : ${items}" th:text="${item.description}">Item description here...</li>
</ul>
同一个标签属性有不同的优先级,级别高的输出
级别 | 说明 | 属性 |
---|---|---|
1 | 片段引入 | th:insert th:replace |
2 | 迭代 | th:each |
3 | 条件判断 | th:if th:unless th:switch th:case |
4 | 局部变量定义 | th:object th:with |
5 | 一般属性修改 | th:attr th:attrprepend th:attrappend |
6 | 特定属性修改 | th:value th:href th:src``... |
7 | 文本(标签体修改) | th:text th:utext |
8 | 片段规范 | th:fragment |
9 | 片段去除 | th:remove |
这个优先机制意味着如果属性位置被反转,上述迭代片段将给出完全相同的结果(尽管它的可读性稍差
<ul>
<li th:text="${item.description}" th:each="item : ${items}">Item description here...</li>
</ul>
标准的HTML / XML注释可以在Thymeleaf模板的任何地方使用。这些注释中的任何内容都不会被Thymeleaf处理,并将逐字复制到结果中:
<!-- User info follows -->
<div th:text="${...}">
...
</div>
从模板中简单删除:
<!--/* This code will be removed at Thymeleaf parsing time! */-->
Thymeleaf将删除之间的所有内容,因此,当模板静态打开时,这些注释块也可用于显示代码,因为知道在Thymeleaf处理它时将被删除
<!--/*-->
<div>
you can see me only before Thymeleaf processes me!
</div>
<!--*/-->
<table>
<tr th:each="x : ${xs}">
...
</tr>
<!--/*-->
<tr>
...
</tr>
<tr>
...
</tr>
<!--*/-->
</table>
当模板静态打开(即作为原型)时,Thymeleaf允许定义标注为注释的特殊注释块,但在执行模板时,Thymeleaf被认为是正常的标记。
<span>hello!</span>
<!--/*/
<div th:text="${...}">
...
</div>
/*/-->
<span>goodbye!</span>
Thymeleaf的解析系统将简单地删除和标记,而不是其内容,因此将被遗弃。
<span>hello!</span>
<div th:text="${...}">
...
</div>
<span>goodbye!</span>
与解析器级注释块一样,此功能与方言无关。
th:block
标签th:block
仅仅是一个属性的容器,它允许开发人员模板指定哪个属性他们想要的。Thymeleaf将执行这些属性,然后简单地使块,而不是它的内容消失。
因此,它可能是有用的,例如,在创建需要一个以上的迭代表时,<tr>
每个元素:
<table>
<th:block th:each="user : ${users}">
<tr>
<td th:text="${user.login}">...</td>
<td th:text="${user.name}">...</td>
</tr>
<tr>
<td colspan="2" th:text="${user.address}">...</td>
</tr>
</th:block>
</table>
尤其是有用的,只有原型的注释块组合使用时:
<table>
<!--/*/ <th:block th:each="user : ${users}"> /*/-->
<tr>
<td th:text="${user.login}">...</td>
<td th:text="${user.name}">...</td>
</tr>
<tr>
<td colspan="2" th:text="${user.address}">...</td>
</tr>
<!--/*/ </th:block> /*/-->
</table>
请注意,此解决方案如何帮助模板是有效的HTML(无需添加禁止<div>
内部块<table>
),并且仍然工程确定在浏览器中打开时,如静态的原型!