无论文本是文字还是计算变量或消息表达式的结果,都可以使用“+”运算符轻松地追加文本:
<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}|">
注意:只有变量/信息表达式(${...}, *{...}, #{...})可以在 |...| 文本替换中使用。其他字面符号('...')、布尔/数字标记、条件表达式等都不允许。
Thymeleaf 中还提供了一些算术运算:+、-、*、/ 和 %,例如:
<div th:with="isEven=(${prodStat.count} % 2 == 0)">
注意:这些运算符也可以应用于 OGNL 变量表达式本身(在这种情况下,将由 OGNL 而不是 Thymeleaf 标准表达式引擎执行),例如:
<div th:with="isEven=${prodStat.count % 2 == 0}">
注意,其中一些运算符存在文本别名:div(/),mod(%)。
表达式中的值可以用 >、<、>= 和 <= 符号进行比较,而 == 和 != 运算符可以用来检查是否相等(或不相等)。请注意,XML 规定 < 和 > 符号不应该在属性值中使用,因此应该使用 < 和 > 实体分别取代 < 和 > 符号。
<div th:if="${prodStat.count} > 1"> <span th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')">
一个更简单的替代方法是使用这些运算符的文本别名去替换实体:gt(>),lt(<),ge(>=),le(<=),not(!),eq(==),neq/ne(!=)。
条件表达式仅用于根据条件(本身可以是表达式)的求值结果来计算两个表达式中的一个。让我们来看一个示例片段(引入另一个属性修饰符 th:class):
<tr th:class="${row.even}? 'even' : 'odd'"> ... </tr>
条件表达式的三个部分(条件 ? THEN : ELSE)本身都是表达式,这意味着它们可以是变量(${...}、*{...})、消息(#{...})、URL(@{...})或文本('...')。
条件表达式也可以使用圆括号进行嵌套,例如:
<tr th:class="${row.even} ? (${row.first} ? 'first' : 'even') : 'odd'"> ... </tr>
也可以省略 else 表达式,在这种情况下,如果条件为 FALSE,则返回空值。如下:
<tr th:class="${row.even}? 'alt'"> ... </tr>
默认表达式是一种不带 THEN 部分的特殊条件表达式。
它相当于一些语言(如:Groovy)中的 Elvis 运算符,允许您指定两个表达式:如果计算结果不为空,则使用第一个表达式;如果计算结果为空,则使用第二个表达式。
让我们在我们的用户配置文件页面中看到它的实际效果,如下:
<div th:object="${session.user}"> ... <p>Age: <span th:text="*{age} ? : '(no age specified)'">27</span>.</p> </div>
如您所见,操作符是 ?:,我们在这里使用它来指定一个缺省值(当年龄为空时提示“no age specified”),只有当 *{age} 的求值结果为空时才使用它。因此,这相当于:
<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>
无操作 token 由下划线符号(_)表示。
此 token 背后的思想是指定表达式的期望结果是不执行任何操作,即完全按照根本不存在可处理属性(例如 th:text)的方式执行操作。
这允许开发人员使用原型中的文本作为默认值。例如:
<span th:text="${user.name} ?: 'no user authenticated'">...</span>
我们可以直接使用 ‘no user authenticated’ 作为原型文本,从设计的角度来看,这会产生更简洁、更通用的代码:
<span th:text="${user.name} ?: _">no user authenticated</span>
上面两者实现效果一致。前者通过条件表达式指定默认值,后者直接使用模板中的值 “no user authenticated” 作为默认值。
Thymeleaf 为变量(${...})和选择(*{...})表达式定义了双花括号语法,允许我们通过配置的转换服务应用数据转换。基本上是这样的:
<td th:text="${{user.lastAccessDate}}">...</td>
注意到那里的双花括号了吗?${{...}}。
它指示 Thymeleaf 将 user.lastAccessDate 表达式的结果传递给转换服务,并要求它在写入结果之前执行格式化操作(转换为字符串)。
假设 user.lastAccessDate 的类型为 java.util.Calendar,如果已注册转换服务(IStandardConversionService 的实现)并包含 Calendar->String 的有效转换,则将应用该转换服务。
IStandardConversionService(StandardConversionService类)的默认实现只是对任何转换为字符串的对象执行 .toString()。
注意:官方的 Thymeleaf-Spring3 和 Thymeleaf-Spring4 集成包透明地将 Thymeleaf 的转换服务机制与 Spring 自己的转换服务基础设施集成在一起,因此在 Spring 配置中声明的转换服务和格式化程序将自动用于 ${{...}} 和 *{{...}} 表达式。
除了用于表达式处理的所有这些功能外,Thymeleaf 还具有预处理表达式的功能。预处理是在正常的表达式之前进行执行,允许修改最终将被执行的表达式。
预处理过的表达式与普通表达式完全一样,但出现时周围有一个双下划线符号(如 __${表达式}__ )。
让我们想象一下,我们有一个 i18n Messages_fr.properties 条目,其中包含一个调用特定语言静态方法的 OGNL 表达式,比如:
article.text=@myapp.translator.Translator@translateToFrench({0})
和 Messages_es.Properties 等效项:
article.text=@myapp.translator.Translator@translateToSpanish({0})
我们可以创建一个标记片段,根据区域设置计算一个或另一个表达式的值。为此,我们将首先选择表达式(通过预处理),然后让 Thymeleaf 执行它:
<p th:text="${__#{article.text('textVar')}__}">Some text here...</p>
请注意,法语区域设置的预处理步骤将创建以下等效项:
<p th:text="${@myapp.translator.Translator@translateToFrench(textVar)}">Some text here...</p>
可以使用 \_\_ 在属性中转义预处理字符串 __。