前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Thymeleaf模板常用知识点thymeleaf介绍标准表达式语法常用th标签设置属性值Thymeleaf迭代循环

Thymeleaf模板常用知识点thymeleaf介绍标准表达式语法常用th标签设置属性值Thymeleaf迭代循环

作者头像
JavaEdge
发布2018-05-16 11:52:54
2.9K0
发布2018-05-16 11:52:54
举报
文章被收录于专栏:JavaEdgeJavaEdge

thymeleaf 是新一代的模板引擎,在spring4.0中推荐使用thymeleaf来做前端模版引擎。

thymeleaf介绍

简单说, Thymeleaf 是一个跟 Velocity、FreeMarker 类似的Java模板引擎,它可以完全替代 JSP 。相较与其他的模板引擎,它有如下三个极吸引人的特点:

  • 1.Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它遵从web标准,支持 HTML 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。
  • 2.Thymeleaf 开箱即用的特性,语法优雅易懂。它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、该jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。
  • 3.Thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。

标准表达式语法

它们分为四类:

  • 1.变量表达式
  • 2.选择或星号表达式
  • 3.文字国际化表达式
  • 4.URL表达式

变量表达式

变量表达式即OGNL表达式或Spring EL表达式(在Spring术语中也叫model attributes)。如下所示: ${session.user.name} 它们将以HTML标签的一个属性来表示: <span th:text="${book.author.name}">

选择(星号)表达式

选择表达式很像变量表达式,不过它用一个当前选择的对象来代替整个上下文变量映射来执行,如下: *{customer.name} 被指定的object由th:object属性定义:

代码语言:javascript
复制
<div th:object="${book}">
... 
<span th:text="*{title}">...</span> 
...
</div>

文字国际化(外部化,i8n,消息)表达式

文字国际化表达式允许我们从一个外部文件获取区域文字信息(.properties),用Key索引Value,还可以提供一组参数(可选).

代码语言:javascript
复制
#{main.title} 
#{message.entrycreated(${entryId})}

可以在模板文件中找到这样的表达式代码:

代码语言:javascript
复制
  <table>  
      ...  
      <th th:text="#{header.address.city}">...</th>  
      <th th:text="#{header.address.country}">...</th>  
      ...  
    </table>
  <table>  
      ...  
      <th th:text="#{header.address.city}">...</th>  
      <th th:text="#{header.address.country}">...</th>  
      ...  
    </table>  

URL链接表达式

指的是把一个有用的上下文或回话信息添加到URL,这个过程经常被叫做URL重写。 @{/order/list} URL还可以设置参数: @{/order/details(id=${orderId})} 绝对路径: http://www.thymeleaf.org

链接相对表达式

让我们看这些表达式:

代码语言:javascript
复制
 <form th:action="@{/createOrder}">  
    <a href="main.html" th:href="@{/main}">```
 <form th:action="@{/createOrder}">  
    <a href="main.html" th:href="@{/main}">

分段表达式

变量表达式和星号表达有什么区别吗?

如果不考虑上下文的情况下,两者没有区别;星号语法评估在选定对象上表达,而不是整个上下文

什么是选定对象?就是父标签的值,如下:

代码语言:javascript
复制
 <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>

这是完全等价于:

代码语言:javascript
复制
 <div th:object="${session.user}">
      <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>

当然,美元符号和星号语法可以混合使用:

代码语言:javascript
复制
<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>

表达式支持的语法

字面(Literals)
  • 文本文字(Text literals): <p> Now you are looking at a <span th:text="'working web application'">template file</span>. </p>
  • 数字文本(Number literals): <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 literals): <div th:if="${user.isAdmin()} == false"> ...
  • 空(Null literal): <div th:if="${variable.something} == null"> ...
  • 文字标记(Literal tokens): <div th:class="content">...</div>
文本操作(Text operations)
  • 字符串连接(String concatenation):+
  • 文本替换(Literal substitutions):|The name is ${name}| #### 算术运算(Arithmetic operations)
  • 二元运算符(Binary operators): +, -, *, /, % * 减号(单目运算符)Minus sign (unary operator):-
布尔操作(Boolean operations)
  • 二元运算符(Binary operators):and, or
  • 布尔否定(一元运算符)Boolean negation (unary operator):!, not
比较和等价(Comparisons and equality)

比较(Comparators): >, <, >=, <= (gt, lt, ge, le) xml文件禁用<,> 等值运算符(Equality operators):==, != (eq, ne) <div th:if="${prodStat.count} &gt; 1"> <span th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')">

条件运算符(Conditional operators)

If-then: (if) ? (then) If-then-else: (if) ? (then) : (else) Default: (value) ?: (defaultvalue) 所有这些特征可以被组合并嵌套: 'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))

常用th标签

还有非常多的标签,这里只列出最常用的几个,由于一个标签内可以包含多个th:x属性,其生效的优先级顺序为: include,each,if/unless/switch/case,with,attr/attrprepend/attrappend,value/href,src ,etc,text/utext,fragment,remove。

设置属性值

1 Thymeleaf设置任何属性的值

代码语言:javascript
复制
<form action="subscribe.html">
  <fieldset>
    <input type="text" name="email" />
    <input type="submit" value="Subscribe!" />
  </fieldset>
</form>

和Thymeleaf一样,这个模板更像一个静态的原型,而不是一个Web应用程序的模板。首先,action我们表单中的属性静态链接到模板文件本身,这样就没有有用的URL重写的地方。其次,value提交按钮中的属性使其显示英文文本,但我们希望它是国际化的。

然后输入th:attr属性,以及更改其设置标签的属性值的能力:

代码语言:javascript
复制
<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>

这个概念非常简单:th:attr只需要一个为属性赋值的表达式。创建了相应的控制器和消息文件后,处理这个文件的结果是:

代码语言:javascript
复制
<form action="/gtvg/subscribe">
  <fieldset>
    <input type="text" name="email" />
    <input type="submit" value="¡Suscríbe!"/>
  </fieldset>
</form>

除了新的属性值之外,还可以看到应用程序上下文名称已经被自动添加到/gtvg/subscribe前面章节中介绍的URL基址的前面。

但是,如果我们想一次设置多个属性呢?XML规则不允许您在标签中设置两次属性,因此th:attr会使用逗号分隔的分配列表,如下所示:

代码语言:javascript
复制
<img src="../../images/gtvglogo.png" 
     th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />

给定所需的消息文件,这将输出:

代码语言:javascript
复制
<img src="/gtgv/images/gtvglogo.png" title="Logo de Good Thymes" alt="Logo de Good Thymes" />

2 Thymeleaf将值设置为特定的属性

你可能会想这样: <input type="submit" value="Subscribe!" th:attr="value=#{subscribe.submit}"/> 是一个非常丑陋的标记。在一个属性值中指定一个赋值可能是非常实用的,但是如果你必须一直这样做的话,它不是创建模板的最优雅的方法。

Thymeleaf与你一致,这就是为什么th:attr在模板中很少使用。通常情况下,您将使用其他th:*任务设置特定标签属性的属性(而不仅仅是任何属性th:attr)

例如,要设置value属性,请使用th:value:

代码语言:javascript
复制
<input type="submit" value="Subscribe!" th:value="#{subscribe.submit}"/>

看起来好多了,让我们试着action对form标签中的属性做同样的事情:

代码语言:javascript
复制
<form action="subscribe.html" th:action="@{/subscribe}">

你还记得th:href我们home.html之前放的那些吗?他们正是这种属性:

代码语言:javascript
复制
<li>
    <a href="product/list.html" th:href="@{/product/list}">
      Product List
   </a>
</li>

3 Thymeleaf固定值布尔属性

HTML具有布尔属性的概念,没有值的属性和一个意味着值是“真”的属性

例如checked:

代码语言:javascript
复制
<input type="checkbox" name="option2" checked /> <!-- HTML -->
<input type="checkbox" name="option1" checked="checked" /> <!-- XHTML -->

标准方言包含的属性允许您通过评估一个条件来设置这些属性,以便如果评估为true,则该属性将被设置为其固定值,如果评估为false,则该属性将不会被设置:

代码语言:javascript
复制
<input type="checkbox" name="active" th:checked="${user.active}" />

Thymeleaf迭代循环

迭代基础

th:each java.util.List类不是唯一可用于Thymeleaf迭代的值。有一组相当完整的对象被认为可以被迭代 1、任何对象的实现 java.util.Iterable 2、任何对象的实现java.util.Enumeration。 3、任何实现的对象java.util.Iterator,其值将被迭代器返回使用,而不需要缓存内存中的所有值。 4、任何对象的实现java.util.Map。当迭代映射时,iter变量将是类的java.util.Map.Entry。 5、任何数组。 6、任何其他对象将被视为包含对象本身的单值列表。

状态变量

使用时th:each,Thymeleaf提供了一个有用的机制来跟踪迭代状态:状态变量。 状态变量在一个th:each属性中定义并包含以下数据: . 当前迭代索引,从0开始。这是index属性。 . 当前迭代索引,从1开始。这是count属性。 . 迭代变量中的元素总数。这是size财产。 . 每个迭代的iter变量。这是current财产。 . 目前的迭代是偶数还是奇数。这些是even/odd布尔属性。 . 目前的迭代是否是第一个。这是first布尔属性。 . 目前的迭代是否是最后一个。这是last布尔属性。

代码语言:javascript
复制
<table>
  <tr>
    <th>NAME</th>
    <th>PRICE</th>
    <th>IN STOCK</th>
  </tr>
  <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>
</table>

状态变量(iterStat在本例中)是th:each通过在iter变量本身之后写入名称来定义的,用逗号分隔。就像iter变量一样,状态变量的范围也是由持有th:each属性的标签定义的代码片段。

条件语句

有时,如果满足某个条件,则需要模板的一部分才能显示在结果中。

例如,想象一下,我们希望在产品表中显示每个产品存在的评论数量的列,如果有任何评论,则可以链接到该产品的评论详细信息页面。 为了做到这一点,我们将使用th:if属性:

如果值不为空: . 如果value是一个布尔值并且是true。 . 如果值是一个数字并且是非零的 . 如果值是一个字符,并且是非零的 . 如果value是一个String而不是“false”,“off”或“no” . 如果值不是布尔值,数字,字符或字符串。 (如果值为null,则th:如果将评估为false)。 此外,th:if还有一个反向属性,th:unless我们可以在前面的示例中使用它,而不是not在OGNL表达式中使用:

还有一种方法可以在Java中使用相当于开关结构的有条件显示内容:th:switch/ th:case属性集。

代码语言:javascript
复制
<div th:switch="${user.role}">
  <p th:case="'admin'">User is an administrator</p>
  <p th:case="#{roles.manager}">User is a manager</p>
</div>

请注意,只要一个th:case属性被评估为true,th:case同一交换机上下文中的每一个其他属性都被评估为false。

默认选项被指定为th:case="*":

代码语言:javascript
复制
<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>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.01.27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • thymeleaf介绍
  • 标准表达式语法
    • 变量表达式
      • 选择(星号)表达式
        • 文字国际化(外部化,i8n,消息)表达式
          • URL链接表达式
            • 分段表达式
              • 变量表达式和星号表达有什么区别吗?
                • 表达式支持的语法
                • 常用th标签
                • 设置属性值
                  • 1 Thymeleaf设置任何属性的值
                    • 2 Thymeleaf将值设置为特定的属性
                      • 3 Thymeleaf固定值布尔属性
                      • Thymeleaf迭代循环
                        • 迭代基础
                          • 状态变量
                            • 条件语句
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档