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

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属性定义:

<div th:object="${book}">
... 
<span th:text="*{title}">...</span> 
...
</div>

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

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

#{main.title} 
#{message.entrycreated(${entryId})}

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

  <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

链接相对表达式

让我们看这些表达式:

 <form th:action="@{/createOrder}">  
    <a href="main.html" th:href="@{/main}">```
 <form th:action="@{/createOrder}">  
    <a href="main.html" th:href="@{/main}">

分段表达式

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

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

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

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

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

<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设置任何属性的值

<form action="subscribe.html">
  <fieldset>
    <input type="text" name="email" />
    <input type="submit" value="Subscribe!" />
  </fieldset>
</form>

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

然后输入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>

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

<form action="/gtvg/subscribe">
  <fieldset>
    <input type="text" name="email" />
    <input type="submit" value="¡Suscríbe!"/>
  </fieldset>
</form>

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

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

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

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

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

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

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

<input type="submit" value="Subscribe!" th:value="#{subscribe.submit}"/>

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

<form action="subscribe.html" th:action="@{/subscribe}">

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

<li>
    <a href="product/list.html" th:href="@{/product/list}">
      Product List
   </a>
</li>

3 Thymeleaf固定值布尔属性

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

例如checked:

<input type="checkbox" name="option2" checked /> <!-- HTML -->
<input type="checkbox" name="option1" checked="checked" /> <!-- XHTML -->

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

<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布尔属性。

<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属性集。

<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="*":

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Keegan小钢

Android技术积累:开发规范

上个月发布了Android项目重构的三篇系列文章,其中,界面篇中提到了在项目中保持规范性的重要性,也有简单举了几个例子。这篇文章则将其延伸,提供更完整的开发规范...

13420
来自专栏desperate633

我的javascript学习之路_01之js基础1JavaScript的简介JavaScript的使用JavaScript输出javascript语句JavaScript注释JavaScript变量J

近期开始接触学习extjs框架。该框架是基于JavaScript的。为了更好地理解学习extjs,必然需要先对JavaScript有一个较好的理解。

7920
来自专栏前端儿

SASS用法指南

SASS是ruby写的,所以要想将sass编译成css文件,就给配上ruby环境。

18320
来自专栏源码之家

EXCEL快速合并相同值

21650
来自专栏Brian

Python进阶教程(三)

Python 进阶 我们在Python进阶教程(二),介绍了一些Python进阶用法。今天给大家介绍的是和c/c++混合编程的用法。我们都知道特别是Python...

38240
来自专栏陈纪庚

vue.js响应式原理解析与实现—实现v-model与{{}}指令

上一节我们已经分析了vue.js是通过Object.defineProperty以及发布订阅模式来进行数据劫持和监听,并且实现了一个简单的demo。今天,我们就...

23520
来自专栏Golang语言社区

【前端基础】JS基础学习笔记整理

JavaScript是一种基于对象的脚本编程语言,是浏览器上的程序语言。当web容器输出内容到浏览器时,这个内容是包含js源代码的,此时,JavaScript可...

48570
来自专栏Java3y

JSP第五篇【JSTL的介绍、core标签库、fn方法库、fmt标签库】

什么是JSTL JSTL全称为 JSP Standard Tag Library 即JSP标准标签库。 JSTL作为最基本的标签库,提供了一系列的JSP标签,实...

36550
来自专栏飞雪无情的博客

Go语言实战笔记(二十五)| Go Struct Tag

在上一篇介绍Go反射的时候,提到了如何通过反射获取Struct的Tag,这一篇文章主要就是介绍这个的使用和原理,在介绍之前我们先看一下JSON字符串和Struc...

11220
来自专栏前端迷

头条秋招面试题以及答案

答案: 定义 3D 转换,只是用 Z 轴的值。 拓展: transform 属性向元素应用 2D 或 3D 转换。该属性允许我们对元素进行旋转、缩放、移动或倾斜...

12030

扫码关注云+社区

领取腾讯云代金券