1 介绍

1.1 简介

  Thymeleaf是一个用于Web和独立Java环境的模板引擎,能够处理HTML、XML、JavaScript、CSS甚至纯文本。能轻易的与Spring MVC等Web框架进行集成作为Web应用的模板引擎。与其它模板引擎(比如FreeMaker)相比,Thymeleaf最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个Web应用(更加方便前后端分离,比如方便类似VUE前端设计页面),抛弃JSP吧。
  Thymeleaf 3.0是一个完全彻底重构的模板引擎(官网原文:Thymeleaf 3.0 builds around a completely new template processing engine),极大的减少内存占用和提升性能和并发性,避免v2.1版因大量的输出标记的集合产生的资源占用。
  Thymeleaf 3.0放弃了大多数面向DOM的处理机制,变成了一个基于事件的模板处理器,它通过处理模板标记或文本并立即生成其输出,甚至在新事件之前响应模板解析器/缓存事件。Thymeleaf是Spring Boot官方的推荐使用模板。

3.0版的模型解析事件模型:

2.1的性能和Velocity、Freemarker原先十几倍的差距,到了2015年的3.0版时已经在显著缩小,但目前性能还是和主流引擎有差距,见:

https://github.com/jreijn/spring-comparing-template-engines/issues/19

1.2 模板类型

允许您处理六种模板,有:

- HTML
- XML
- TEXT
- JAVASCRIPT
- CSS
- RAW

2 标准表达式语法

2.1 简单表达式

  • 变量表达式: ${...}
  • 选择变量表达式: *{...}
  • 消息表达式: #{...}
  • URL 表达式: @{...}
  • 代码段表达式: ~{...}

变量表达式 Variable expressions: ${...}

变量表达式在Spring中就是模型属性

例如:${user.name}
定义在属性中:<span th:text="${book.author.name}">
遍历:<li th:each="book : ${books}">

<!-- springmvc 保存了一个 model 对象: departments -->

<!-- 获取所有 departments -->
<p th:text="${departments}"></p>
<!-- 获取 departments 的第一个元素 -->
<p th:text="${departments[0]}"></p>
<!-- 获取第一个 department 对象的 name 属性 -->
<p th:text="${departments[0].name}"></p>
<!-- 也可以用 ['name'] 来获取第一个 department 对象的 name 属性 -->
<p th:text="${departments[0]['name']}"></p>
<!-- 甚至可以调用方法! -->
<p th:text="${departments[0].getId()}"></p>
<p th:text="${departments[0]['name'].substring(0, 1)}"></p>

选择变量表达式 Selection expressions: *{...}

选择表达式就像变量表达式,它们用于先前选择的对象上执行,而不是在整个上下文变量映射中执行。
只要是没有选择的对象,选择表达式与变量表达式的语法是完全一样的。那什么是选择的对象呢?是一个:th:object对象属性绑定的对象。

例如:*{customer.name}
展示book变量的属性:

<div th:object="${book}">
<span th:text="*{title}">...</span>
</div>
<div th:object="document[2]">
<!-- 以下三种方式在这种情况下是等价的 -->
<p th:text="${#object.id}"></p>
<p th:text="*{id}"></p>
<p th:text="${document[2].id}"></p>
</div>

消息表达式 Message expressions: #{...}

消息表达式用于展示静态资源的内容,比如i18n属性配置文件

例如:#{main.title}
一个完整的例子:

<table>
...
<th th:text="#{header.address.city}">...</th>
<th th:text="#{header.address.country}">...</th>
...
</table>
<!-- 还可以结合变量表达式使用 -->
#{${config.welcomeKey}}

比如新建/WEB-INF/templates/home.properties,home.welcome的内容:home.welcome=this messages is from home.properties!
使用消息表达式:<p th: text=" #{home.welcome}" >This text will not be show! </p>

一个更深入的例子:

结合消息表达式、变量表达式、预处理表达式

#{home.__${sel.code}__}

看上去很乱是吧,实际上可以分解成3步:
1、先计算变量${sel.code},假如值是welcome
2、__的含义是需要预处理的变量值,那么就变成#{home.welcome}
3、计算最终结果,简单吧

URL 表达式 Link (URL) expressions: @{...}

例如:<a th:href="@{/order/list}">...</a>
带参数的URL:<a th:href="@{/order/details(id=${orderId},type=${orderType})}">...</a>
相对地址:<a th:href="@{../documents/report}">...</a>
绝对地址:<a th:href="@{http://www.mycompany.com/main}">...</a>

代码段表达式 Fragment expressions: ~{...}

用于整段内容的引用。
例如:<div th:insert="~{commons :: main}">...</div>

整体的例子:

<div th:with="frag=~{footer :: #main/text()}">
<p th:insert="${frag}">
</div>

详细介绍:https://github.com/thymeleaf/thymeleaf/issues/451

2.2 文字和操作

  • 文本字面量: 'some text'
  • 数值字面量: 0, 34, 3.0, 12.3
  • 布尔值字面量: true, false
  • Null 值字面量: null
  • Tokens 字面量: one, content, sometext, ...

文本操作符

  • 字符串连接: +

比如附加字符:<span th:text="'The name of the user is ' + ${user.name}">

  • 字面量替换: |The name is ${name}|

字面量替换主要用于连接字符,比如<span th:text="|The name of the user is ${user.name}|">就和上面的一样

算术操作符

  • 二元操作符: +, -, *, /, %
  • 负数(一元操作符): -

布尔操作符(逻辑操作符)

  • 二元操作符: and, or
  • 非(一元操作符): !, not

比较操作符

  • 比较: >, <, >=, <= (gt, lt, ge, le)
  • 相等性: ==, != (eq, ne)

条件操作符

  • if-then: (if) ? (then)
  • if-then-else: '(if) ? (then) : (else)'
  • 默认: (value) ?: (defaultvalue)

2.3 特殊符号

忽略操作 No-Operation token: _

例子:<div id="main" th:text="${data.hasId()} ? ${data.value} : _">...</div>

如变量${data.hasId()} == true ,则输出类似:<div id="main" text="模型的value值">...</div>
如变量${data.hasId()} == false ,则输出类似:<div id="main">...</div>

解耦模板逻辑 Decoupled Template Logic

见:https://github.com/thymeleaf/thymeleaf/issues/465

转义

比如<p th:text="'man, <br>Let\'s</br> fish!'"></p>
因为Let's包含 ' , 得用 \ 进行转义
输出:man, <br>Let's</br> fish!

非转义文本 Unescaped Text

假如配置文件为:home.welcome=Welcome to our <b>fantastic</b> grocery store!
直接使用会造成问题,输出:<p>Welcome to our &lt;b&gt;fantastic&lt;/b&gt; grocery store!</p>
使用th:utext可以解决问题,如:
<p th:utext="#{home.welcome}"></p>

输出就是fantastic加粗体的文本:<p>Welcome to our <b>fantastic</b> grocery store!</p>
记得非转义文本用th:utext,不要用th:text哦

预处理表达式

#{home.__${sel.code}__}

看上去很乱是吧,实际上可以分解成3步
1、先计算变量${sel.code},假如值是welcome
2、__的含义是需要预处理的变量值,那么就变成#{home.welcome}
3、计算最终结果,简单吧

默认处理表达式 Default expressions (Elvis operator)

如果变量为空或者不满足then条件,就用默认值,如:

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

等同:

<p>Age: <span th:text="*{age != null}? *{age} : '(no age specified)'">27</span>.</p>

3 数据遍历

使用th:each属性

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

其中iterStat用于定义遍历的状态,比如是奇数还是偶数(iterStat.odd是奇)iterStat.even是偶数。
还有其他的属性:

  • index :当前迭代索引,从0开始。这是索引属性。
  • count :当前迭代索引,从1开始。这是计数属性。
  • size :迭代变量中的元素总数。这是尺寸的属性。
  • current :iter变量用于每次迭代。这是当前属性。
  • even/odd :当前迭代是偶数还是奇数。这些是偶/奇布尔性质。
  • first :当前迭代是否是第一次迭代。这是第一个布尔属性。
  • last :当前迭代是否为最后一次迭代。这是最后一个布尔属性。

条件if表达式

<table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
<th>COMMENTS</th>
</tr>
<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>
<td>
<span th:text="${#lists.size(prod.comments)}">2</span> comment/s
<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:if="${not #lists.isEmpty(prod.comments)}">view</a>
</td>
</tr>
</table>

使用th:switch替代if

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

Thymeleaf教程入门到深入1:基础介绍的更多相关文章

  1. 通达OA 小飞鱼工作流在线培训教程(一)HTML基础介绍

    应一些刚接触工作流设计朋友的要求,这里开设一个系列教程,对通达OA工作流设计相关的内容做个介绍.方便解决一些日常经常出现的问题,希望对刚刚接触这部分工作的朋友能够有些帮助. 工作流设计须要多方面的知识 ...

  2. OpenCV学习教程入门篇&lt;一、介绍&gt;

    OpenCV,是Inter公司开发的免费开源专门因为图像处理和机器视觉的C/C++库,英文全称是Open Source Computer Vision. 1. 可视化语言Matlab与OpenCV都能 ...

  3. Web3D编程入门总结——WebGL与Three.js基础介绍

    /*在这里对这段时间学习的3D编程知识做个总结,以备再次出发.计划分成“webgl与three.js基础介绍”.“面向对象的基础3D场景框架编写”.“模型导入与简单3D游戏编写”三个部分,其他零散知识 ...

  4. Arduino可穿戴开发入门教程LilyPad和LilyPad Simple的介绍

    Arduino可穿戴开发入门教程LilyPad和LilyPad Simple的介绍 LilyPad和LilyPad Simple的介绍 LilyPad和LilyPad Simple是LilyPad微控 ...

  5. 原创教程:《metasploit新手指南》介绍及下载

    原创教程:<metasploit新手指南>介绍及下载 1.1 作者简介 这份教程并不是“玄魂工作室”原创,但是我还是要力推给大家.相比那些一连几年都在问“我怎么才能入门”的人而言,我们更欣 ...

  6. Thymeleaf从入门到精通

    什么是Thymeleaf 大家好,我是bigsai,今天我们来学习Thymeleaf,如果你对Thymeleaf比较陌生也不要紧,它很容易学习与理解,并有着自己鲜明的特色. 开始之前,我们依旧问一个问 ...

  7. vue 快速入门 系列 —— vue 的基础应用(上)

    其他章节请看: vue 快速入门 系列 vue 的基础应用(上) Tip: vue 的基础应用分上下两篇,上篇是基础,下篇是应用. 在初步认识 vue一文中,我们已经写了一个 vue 的 hello- ...

  8. 深度学习与CV教程(2) | 图像分类与机器学习基础

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/37 本文地址:http://www.showmeai.tech/article-det ...

  9. 深度学习与CV教程(8) | 常见深度学习框架介绍

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/37 本文地址:http://www.showmeai.tech/article-det ...

随机推荐

  1. BuildTool

    (一)BuildTool是什么 BuildTool 构建工具  ,是一个把源代码生成可执行应用程序的过程自动化的程序(例如Android app生成apk).构建包括编译.连接跟把代码打包成可用的或可 ...

  2. Swagger注解

    swagger注解说明  1.与模型相关的注解,用在bean上面 @ApiModel:用在bean上,对模型类做注释: @ApiModelProperty:用在属性上,对属性做注释 2.与接口相关的注 ...

  3. idea常用快捷键及操作

    ctrl+j  ===== 智能提示 可用模版及关键字 ctrl+p ===== 显示方法可填入的参数 ctrl+space ===== 补全提示项目中可用的变量 ctrl+shift+j  ==== ...

  4. Java学习笔记(二十二):打包程序

    加入一个程序测试完毕,我们就可以将它打包,就可以放到服务器上运行了 找到左下角的终端 点击 输入命令: mvnw clean package -DskipTests=true clean:清除以前生成 ...

  5. VueJs学习笔记

      在cmd下,进入目录之后 cd 到项目目录下 1 安装node cnpm install   2 启动或者调试 cnpm start (或是npm run dev) 3 上线: npm run b ...

  6. C++重写(覆盖)、重载、重定义、

    总结: 重写(覆盖)override 是指派生类函数重写(覆盖)基类函数 不同的范围,分别位于基类和派生类中 函数的名字相同 参数相同 基类函数必须有virtual关键字 重载overload 成员函 ...

  7. 560. Subarray Sum Equals K 求和为k的子数组个数

    [抄题]: Given an array of integers and an integer k, you need to find the total number of continuous s ...

  8. 记一次SQL性能优化,查询时间从4000ms优化到200ms.

    以下这句SQL是从PLM中获取代办工作流的.没优化前SQL语句执行一次大概4000ms(4秒). select ch.change_number changeNumber, f.text change ...

  9. php base64上传图片

    php实现base64图片上传方式 本例子中没有采用File Post上传文件方式!原理一样,为了更加的理解base64 选择将其输出在文本域中,并提交至服务器!运用到项目中建议采用提交File方式. ...

  10. 2019.02.12 bzoj3944: Sum(杜教筛)

    传送门 题意: 思路:直接上杜教筛. 知道怎么推导就很简单了,注意预处理的范围. 然后我因为预处理范围不对被zxyoi教育了(ldx你这个傻×两倍常数活该被卡TLE) 喜闻乐见 代码: #includ ...