Thymeleaf标准表达式语法

本文详细介绍了Thymeleaf的表达式语法,包括信息表达式、变量表达式、选择表达式、URL链接、基本类型操作以及各种运算和条件表达式。还探讨了Thymeleaf提供的对象,如#dates、#numbers和#strings等,以及在模板中如何格式化日期、创建URL链接和进行条件判断。同时,文章展示了如何利用预处理表达式和设置属性值来处理动态内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Thymeleaf标准表达式语法

两种简单语法:
<p th:utext="#{home.welcome}">Welcome to our grocery store!</p>
<p>Today is: <span th:text="${today}">13 february 2011</span></p>
  • 简单表示式:

    • 变量表达式: ${…}
    • 选择变量表达式: *{…}
    • 信息表达式: #{…}
    • URL连接表达式: @{…}
  • 文字类型:

    • 字符型: ‘one text’ , ‘Another one!’ ,…
    • 数值型: 0 , 34 , 3.0 , 12.3 ,…
    • Boolean型: true , false
    • 空值: null
    • 文本字符串: one , sometext , main ,…
  • 字符串操作:
    • 字符串连接: +
    • 文字替换: |The name is ${name}|
  • 数值型操作:
    • 运算符: + , - , * , / , %
    • 负号: -
  • Boolean操作:
    • 运算符: and , or
    • 非运算符: ! , not
  • 比较相等算法:
    • 比较: > , < , >= , <= ( gt , lt , ge , le )
    • 相等算法: == , != ( eq , ne )
  • 条件语句:

    • If-then: (if) ? (then)
    • If-then-else: (if) ? (then) : (else)
    • Default: (value) ?: (defaultvalue)

    所有上面算法都可以随意组合和嵌套:

'User is of type ' + (${user.isAdmin()} ? 'Administrator': (${user.type} ?: 'Unknown'))

· 条件判断

(if) ? (then) if-then

(if) ? (then) : (else) if-then-else

<tr th:class="${row.even}? 'even' : 'odd'">
  ...
</tr>

条件表达式中的三个部分自身也可以是表达式,也可以是变量(${…}, *{…}), 消息(#{…}), URL (@{…}) 或字面量 (’…’)
条件表达式也可以使用括号来嵌套:

<tr th:class="${row.even}? (${row.first}? 'first' : 'even') : 'odd'">
...
</tr>

else表达式也可以省略,当条件为false时,会返回null:

<tr th:class="${row.even}? 'alt'">
...
</tr>

(value) ?: (defaultvalue) Default
只有在第一个表达式返回null时,第二个表达式才会运算

信息表达式

我们之前的例子是这样的

<p th:utext="#{home.welcome}">Welcome to our grocery store!</p>
home.welcome=欢迎光临本店,

但是有的时候我们需要在消息中增加变量,比如客人的名字怎么办?比如达到如下效果

<p>¡Bienvenido a nuestra tienda de comestibles, 木鱼!</p>

这样办:

home.welcome=欢迎光临本店, {0}!
<p th:utext="#{home.welcome(${session.user.name})}">
¡Bienvenido a nuestra tienda de comestibles, 木鱼!
</p>

在这里,参数可以是字符型也可是树数值型或者日期型。当然如果我们需要多个参数的话,类推即可,并且我们也可以内嵌表达式替换字符串,比如:

<p th:utext="#{${welcomeMsgKey}(${session.user.name})}">
Welcome to our grocery store, 木鱼!
</p>

变量表达式

变量表达式可以解析OGNL语法。详尽的语法信息可以访问官网:
http://commons.apache.org/ognl/

系统基本对象

OGNL有以下基本内置对象

  • #ctx : the context
  • #object. vars: the context variables.
  • #locale : the context locale.
  • #httpServletRequest : (only in Web Contexts)theHttpServletRequest object.
  • #httpSession : (only in Web Contexts) the HttpSession object.
    所以我们可以用如下方式引用:
Established locale country: <span th:text="${#locale.country}">US</span>.

Thymeleaf提供的对象

除了这些基本的对象,Thymeleaf将为我们提供一套实用的对象。来帮助我们我们执行常见的任务。

  • #dates : 为 java.util.Date对象提供工具方法,比如:格式化,提取年月日等.
  • #calendars : 类似于#dates , 但是只针对java.util.Calendar对象.
  • #numbers : 为数值型对象提供工具方法。
  • #strings :为String 对象提供工具方法。如: contains, startsWith, prepending/appending等。
  • #objects : 为object 对象提供常用的工具方法。
  • #bools : 为boolean 对象提供常用的工具方法。
  • #arrays : 为arrays 对象提供常用的工具方法。
  • #lists :为lists对象提供常用的工具方法。
  • #sets : 为sets对象提供常用的工具方法。
  • #maps : 为maps对象提供常用的工具方法。
  • #aggregates :为创造一个arrays 或者 collections聚集函数提供常用的工具方法。
  • #messages : utility methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax?.
  • #ids : 为可能需要循环的ID属性提供常用的工具方法。

在我们的主页中重新格式化日期

现在我们知道了Thymeleaf提供的工具类和表达式的语法,那么我们来重新格式化首页的日期吧,首先在我们的controller层中吧字符型日期替换成对象

SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
Calendar cal = Calendar.getInstance();
WebContext ctx = new WebContext(request, servletContext, request.getLocale());
ctx.setVariable("today", dateFormat.format(cal.getTime()));
templateEngine.process("home", ctx, response.getWriter());

替换成

WebContext ctx = new WebContext(request, servletContext, request.getLocale());
ctx.setVariable("today", Calendar.getInstance());
templateEngine.process("home", ctx, response.getWriter());

然后是模板

<p>
Today is: <span th:text="${#calendars.format(today,'dd MMMM yyyy')}">13 May 2011</span>
</p>   

选择表达式用法(*{ })

变量不仅能用在#{ }上,还能用在* { }上。两者的区别在于* { }上的的变量首先是选定对象的变量。如果不选定对象,那么是整个上下文环境中的变量和#{ }相同

选择对象用什么呢?th:object标签属性。我们使用它在我们的用户配置文件(userprofile.html)页面:

<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>

如果一个对象已经被选择,即th:object=”${session.user}”。那么我们也使用#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>

URL链接

URL链接有以下几种类型:   

  • 绝对地址,如http://www.thymeleaf.org
  • 相对地址
    • 页面相对: user/login.html
    • 上下文相对:/itemdetails?id=3 (服务器上下文名称会被自动添加)
    • 服务器相对:~/billing/processInvoice(允许调用同一服务器上的另一个上下文中的URL)

让我们来使用th:href属性:

<!-- 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>

我来解释下:

  • th:href属性修饰符:它将计算并替换使用href链接URL 值,并放入的href属性中。
  • 我们可以使用URL参数的表达式(比如在orderId=${o.id} )
  • 如果需要多个参数,这些将由逗号分隔,比如:@{/order/process(execId=${execId},execType=’FAST’)}
  • 变量也允许URL路径中使用,比如:@{/order/{orderId}/details(orderId=${orderId})}
  • URL中以”/“开头的路径(比如/order/details)将会加上服务器地址和域名。形成完整的URL
  • th:href中可以直接使用静态地址。

URL可以用复杂的表达式:

<a th:href="@{${url}(orderId=${o.id})}">view</a>
<a th:href="@{'/details/'+${user.login}(orderId=${o.id})}">view</a>

现在我们知道如何创建链接的url,那么添加一个小菜单在我们的网站吧

<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>

针对同服务器地址,不同域名的URL。可以这样写@{~/path/to/something}

基本类型操作

字符型

文本文字可以用单引号来包含。需要转义的话可以用\’转义

<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>

Boolean型

boolean型不是true就是false:

<div th:if="${user.isAdmin()} == false"> ...

注意,在上面的例子中,= = false写在括号外,因此是Thymeleaf本身负责解析解析它。如果是写在括号内,它将由OGNL负责解析:

<div th:if="${user.isAdmin() == false}"> ...

 

Null型

<div th:if="${variable.something} == null"> ...

 

Literal tokens(不明白什么意思,大概是字符串文本)

Numeric, boolean 和 null都是字符串文本的一种类型。

只是使表达式更加简洁。工作时终将解析成字符串文本(‘。。。。。。’),但是他们有更多的限制,比如只能用数字(0~9),下划线,.,没有空格,没有逗号等等。

所以当我们仅仅用字符串的话,可以用这种:

<div th:class="content">...</div>

替换掉

<div th:class="'content'">...</div>

 

文本间连接

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}|">

 

注意:${…}表达式可以被放在|….|之间,但是不能放在’….’之间哦

算术运算

也可以用一些算术运算符:+ , - , * , / , % .

th:with="isEven=(${prodStat.count} % 2 == 0)"

 

比较与相等

 > , < , >= ,<=,== 和 !=都可以用,但是<,>这两个在必须转义。

th:if="${prodStat.count} &gt; 1"
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>

可以省略false的返回值,当然如果false那么返回的是一个空值

<tr th:class="${row.even}? (${row.first}? 'first' : 'even') : 'odd'">
...
</tr>

 

默认表达式

默认表达式可以简化表达式,个人不建议用,阅读性差。如:

<div th:object="${session.user}">
...
<p>Age: <span th:text="*{age}?: '(no age specified)'">27</span>.</p>
</div>

解释一下:age如果是null的话就执行’(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>

 

预处理表达式

有的时候我们需要预处理一些信息到表达式中。比如某个变量的名字是变的,怎么办?预处理来了。

预处理表达式用 __${expression}__ 双下划线包裹,举个栗子:
我们在外部资源文件中配了这个属性:

article.text=@myapp.translator.Translator@translateToSpanish({0})

 

我们可以在模板中表达式是这样子的:

<p th:text="${__#{article.text('textVar')}__}">Some text here...</p>

 

那么引擎会首先从资源文件中获取article.text的值,再执行它。

<p th:text="${@myapp.translator.Translator@translateToFrench(textVar)}">Some text here...</p>

 

双下划线可以用\_\_转义

设置属性值

th:attr 任何属性值
<form action="subscribe.html" th:attr="action=@{/subscribe}">
  <fieldset>
    <input type="text" name="email" />
    <input type="submit" value="Subscribe me!" th:attr="value=#{subscribe.submit}"/>
  </fieldset>
</form>

多个属性一起设置,用逗号隔开

<img src="../../images/gtvglogo.png" th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />

设置指定属性

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 ...
<input type="submit" value="Subscribe me!" th:value="#{subscribe.submit}"/>
<form action="subscribe.html" th:action="@{/subscribe}">
<li><a href="product/list.html" th:href="@{/product/list}">Product List</a></li>

设置多个属性在同一时间 有两个特殊的属性可以这样设置: th:alt-title 和 th:lang-xmllang

th:alt-title 设置 alt 和 title
th:lang-xmllang 设置 lang 和 xml:lang

<img src="../../images/gtvglogo.png" th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />

<img src="../../images/gtvglogo.png"th:src="@{/images/gtvglogo.png}" th:title="#{logo}" th:alt="#{logo}" />

<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}" />

编译后:

<input type="button" value="Do it!" class="btn warning" />

还有两个特定的添加属性 th:classappend 和 th:styleappend

<tr th:each="prod : ${prods}" class="row" th:classappend="${prodStat.odd}? 'odd'">

修复的布尔属性

<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 |

HTML5友好的属性及元素名

<table>
    <tr data-th-each="user : ${users}">
        <td data-th-text="${user.login}">...</td>
        <td data-th-text="${user.name}">...</td>
    </tr>
</table>

data-{prefix}-{name}是编写HTML5自定义属性的标准语法,不需要开发者使用th:*这样的命名空间,Thymeleaf让这种语法自动对所有dialect都可用。

遍历

·基础:

<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.Map(遍历时取java.util.Map.Entry)、array、任何对象都被当作只有对象自身一个元素的列表

·状态

  • 当前遍历索引,从0开始,index属性
  • 当前遍历索引,从1开始,count属性
  • 总元素数量,size属性
  • 每一次遍历的iter变量,current属性
  • 当前遍历是even还是odd,even/odd布尔属性
  • 当前遍历是第一个,first布尔属性
  • 当前遍历是最后一个,last布尔属性
<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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值