Thymeleaf(第九十一二章)本地变量#属性优先级#注释和块#内联
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Thymeleaf(第九十一二章)本地变量#属性优先级#注释和块#内联相关的知识,希望对你有一定的参考价值。
9 本地变量
为一个模板的指定片段定义的变量叫做本地变量,只在那个片段里可用。
例如下面这个prod迭代变量:
1<tr th:each="prod : ${prods}">
2...
3</tr>
prod变量只在<tr>标签的界限内可用。特别地:
它将对在这个标签里执行的任何th:*属性都可用,这些属性的优先级要比th:each要低。
它将对任何这个标签的子元素都是可用的,如任何<td>元素。
thymeleaf提供一种方式来声明本地变量,使用th:with属性,它的语法像为属性赋值:
1<div th:with="firstPer=${persons[0]}">
2 <p>
3 The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.
4 </p>
5</div>
当th:with被处理时,firstPer变量被创建为一个本地变量,且添加到来自于上下文的变量map里,因此它可以和任何其它定义在上下文里的变量一起计算,但是仅限于在包含它的那个<div>标签的界限内。
可以一次定义多个变量,使用通常的多赋值语法:
1<div th:with="firstPer=${persons[0]},secondPer=${persons[1]}">
2 <p>
3 The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.
4 </p>
5 <p>
6 But the name of the second person is
7 <span th:text="${secondPer.name}">Marcus Antonius</span>.
8 </p>
9</div>
th:with属性允许在同一个属性里重复使用已定义的变量:
1<div th:with="company=${user.company + ‘ Co.‘},account=${accounts[company]}">...</div>
下面是之前的一个示例:
1<p>
2 Today is:
3 <span th:text="${#calendars.format(today,‘dd MMMM yyyy‘)}">13 february 2011</span>
4</p>
我们可以把日期格式字符串提取出来放入到消息属性文件里:
如home_en.properties:
date.format=MMMM dd‘‘,‘‘ yyyy
另一个home_es.properties:
date.format=dd ‘‘de‘‘ MMMM‘‘,‘‘ yyyy
现在,让我们使用th:with来获取本地化的日期格式到一个变量里,然后把它用在th:text表达式里:
1<p th:with="df=#{date.format}">
2 Today is: <span th:text="${#calendars.format(today,df)}">13 February 2011</span>
3</p>
这非常清晰和简单。事实上,th:with的优先级比th:text高,我们可以把它们两个都写到<span>标签里:
1<p>
2 Today is:
3 <span th:with="df=#{date.format}"
4 th:text="${#calendars.format(today,df)}">13 February 2011</span>
5</p>
10 属性优先级
当你把多个th:*属性写到一个标签里会发生什么?像这样:
1<ul>
2 <li th:each="item : ${items}" th:text="${item.description}">Item description here...</li>
3</ul>
我们希望th:each属性先执行,然后th:text再执行,这样才会产生我们想要的结果。但是html/XML标准并没有给出标签的属性之间的顺序,所以一个优先级机制需要被建立,这样才能按照期望的去工作。
所有的thymeleaf属性都定义了一个数字优先级,这个优先级建立了属性间的执行顺序:
优先级机制意味着属性之间的先后位置变得不再重要,只是阅读起来有点不爽:
1<ul>
2 <li th:text="${item.description}" th:each="item : ${items}">Item description here...</li>
3</ul>
11 注释和块
11.1 标准的HTML/XML注释
标准的HTML/XML注释<!-- ... -->可以用在thymeleaf模板里的任何地方,注释里的任何内容都不会被thymeleaf处理,将会一字不差地被拷贝到输出:
1<!-- User info follows -->
2<div th:text="${...}">
3 ...
4</div>
11.2 thymeleaf解析器级别的注释块
解析器级别的注释块,当thymeleaf执行解析时,将简单地从模板中移除。看起来像这样:
1<!--/* This code will be removed at Thymeleaf parsing time! */-->
thymeleaf将移除所有<!--/和/-->中间的东西。所以当一个模板被静态地打开时,这些注释块能够用来显示代码,当thymeleaf开始处理时,它将被移除:
1<!--/*-->
2 <div>
3 you can see me only before Thymeleaf processes me!
4 </div>
5<!--*/-->
这可以非常方便地用于原型中的表格里的多行<tr>,例如:
1<table>
2 <tr th:each="x : ${xs}">
3 ...
4 </tr>
5 <!--/*-->
6 <tr>
7 ...
8 </tr>
9 <tr>
10 ...
11 </tr>
12 <!--*/-->
13</table>
11.3 thymeleaf仅原型注释块
当模板被静态地打开时,它是注释,当模板被thymeleaf处理时,它被认为是正常的标记。
1<span>hello!</span>
2<!--/*/
3 <div th:text="${...}">
4 ...
5 </div>
6/*/-->
7<span>goodbye!</span>
thymeleaf的解析系统将简单地移除<!--//和//-->记号,保留它的内容,所以当执行模板时,thymeleaf实际上看到的是这样:
1<span>hello!</span>
2
3 <div th:text="${...}">
4 ...
5 </div>
6
7<span>goodbye!</span>
与解析器级别的注释块相比,这个特性是方言独立的。
11.4 人造的th:block标签
thymeleaf的仅有元素处理器(不是属性)包含在标准的方言中,是th:block。
th:block仅仅是一个属性容器,允许模板开发者来指定他们想要的那些属性。
thymeleaf将执行这些属性,然后简单地使这个块(不是它的内容)消失。
因此它可能有用,例如,当创建迭代表格,且每个元素要求多个<tr>标签时:
1<table>
2 <th:block th:each="user : ${users}">
3 <tr>
4 <td th:text="${user.login}">...</td>
5 <td th:text="${user.name}">...</td>
6 </tr>
7 <tr>
8 <td colspan="2" th:text="${user.address}">...</td>
9 </tr>
10 </th:block>
11</table>
也会特别有用,当和仅原型注释块联合使用时:
1<table>
2 <!--/*/ <th:block th:each="user : ${users}"> /*/-->
3 <tr>
4 <td th:text="${user.login}">...</td>
5 <td th:text="${user.name}">...</td>
6 </tr>
7 <tr>
8 <td colspan="2" th:text="${user.address}">...</td>
9 </tr>
10 <!--/*/ </th:block> /*/-->
11</table>
注意,这种解决方案如何允许模板是一个合法的HTML,同时当直接使用浏览器打开作为原型时也工作正常。
12 内联
12.1 表达式内联
虽然使用标签属性能做几乎所有事情,有些情形我们宁愿把表达式直接写到HTML文本里。我们更倾向于这样写:
1<p>Hello, [[${session.user.name}]]!</p>
而不是这样:
1<p>Hello, <span th:text="${session.user.name}">Sebastian</span>!</p>
[[...]]或[(...)]之间的表达式在thymeleaf里被认为是内联表达式,这些表达式可以是原来用在属性里的合法的任何类型的表达式。
注意,[[...]]对应于th:text,将会进行HTML转义,[(...)]对应于th:utext,将不执行HTML转义。所以对于一个这样的变量msg = ‘This is <b>great!</b>‘,下面这个片段:
1<p>The message is "[(${msg})]"</p>
它的结果是不转义,直接输出:
1<p>The message is "This is <b>great!</b>"</p>
然而,如果要转义的话,就像这样:
1<p>The message is "[[${msg}]]"</p>
结果将被进行HTML转义:
1<p>The message is "This is <b>great!</b>"</p>
注意,文本内联默认被激活,因此我们不需要开启它。
内联vs自然模板
如果你使用过其它模板引擎,就会觉得这种输出文本的方式是很平常啊,你可能会问,为什么我们不从一开始就这样做?它比所有的那些th:text属性的代码都要少。
好吧,请小心,因为虽然你发现内联十分有趣,你应该总是要记住,当你以静态的方式打开它时,内联表达式将会一字不差地被显式在HTML中,因此你可能不能够再使用它因为设计原型。
当原型中不使用内联时是这样的:
1Hello, Sebastian!
使用内联是这样的:
1Hello, [[${session.user.name}]]!
从设计实用性的角度来讲,它们之间的差别非常明显。
禁用内联
因为有些场合我们想要[[...]]或[(...)]原样输出而不是作为表达式被处理,此时我们将使用th:inline="none":
1<p th:inline="none">A double array looks like this: [[1, 2, 3], [4, 5]]!</p>
这将输出:
1<p>A double array looks like this: [[1, 2, 3], [4, 5]]!</p>
注:还有文本内联、javascript内联、CSS内联,文章不再列出,需要的可自行查阅官方文档。
(完)
以上是关于Thymeleaf(第九十一二章)本地变量#属性优先级#注释和块#内联的主要内容,如果未能解决你的问题,请参考以下文章