Thymeleaf模板引擎用法总结
Thymeleaf 基本用法总结
一、引用命名空间 <html xmlns:th="http://www.thymeleaf.org">
在html中引入此命名空间,可避免编辑器出现html验证错误,虽然加不加命名空间对Thymeleaf的功能没有任何影响。
二、输出内容
2.1 <p th:text="#{home.welcome}">Welcome to our grocery store!</p>
说明:
1. th:text 用来将内容输出到所在标签的body中。
2. #{home.welcome} 用来引入数据home对象中的 welcome属性。
3. 可以用th:utext 用来显示“unescaped ” 的html内容。
2.2 <p>Today is: <span th:text="${today}">13 February 2011</span></p>
说明:${today} 用来引用 today 变量
三、访问对象
${param.x} 返回名为x 的 request参数。(可能有多个值)
${session.x} 返回名为x的Session参数。
${application.x} 返回名为 servlet context 的参数。
四、基本语法
4.1 #{home.welcome} -- 访问数据
4.2 #{home.welcome(${session.user.name})} -- 格式化数据 当 home.welcome 为 "abcdegf{0}" 类似这种内容时。(多个参数以逗句分隔)。
4.3 ${today} --- 访问变量
4.4 访问基本对象
#ctx: the context object.
#vars: the context variables.
#locale: the context locale.
#request: (only in Web Contexts) the HttpServletRequest object.
#response: (only in Web Contexts) the HttpServletResponse object.
#session: (only in Web Contexts) the HttpSession object.
#servletContext: (only in Web Contexts) the ServletContext object.
其它公共对象参考: http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#appendix-a-expression-basic-objects
4.5 日期的输出
<span th:text="${#calendars.format(today,'dd MMMM yyyy')}">13 May 2011</span>
4.6 星号语法
<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>
4.7 输出URL
<a href="product/list.html" th:href="@{/product/list}">Product List</a>
<a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>
4.8 使用代码段
<div th:insert="~{commons :: main}">...</div>
4.9 直接输出内容
<span th:text="'working web application'"> -- 输出字符
<span th:text="2013 + 2"> -- 输出数据表达式
<div th:if="${user.isAdmin()} == false"> --输出布尔表达式
<span th:text="'Welcome to our application, ' + ${user.name} + '!'"> -- 带变量的
4.10 条件表达式
<tr th:class="${row.even}? 'even' : 'odd'">
...
</tr>
<tr th:class="${row.even}? 'alt'">
...省略 false 结果的表达方式
</tr>
<div th:object="${session.user}">
...省略 true 结果的表达方式
<p>Age: <span th:text="*{age}?: '(no age specified)'">27</span>.</p>
</div>
<span th:text="${user.name} ?: _">no user authenticated</span> --不做任何处理时用下划线 _ 表示
4.11 格式化
<td th:text="${{user.lastAccessDate}}">...</td> --${{.}} 调用默认的格式化器来输出结果。
4.12 预处理
<p th:text="${__#{article.text('textVar')}__}">Some text here...</p>
说明:thymeleaf 的处理模板内容的顺序与书写顺序无关,只能通过 __${expression}__ ,来将需要先一步计算出来后面 要用的变量指定为优化处理。
五、设置 Attribute 值
5.1 设置任何Attribute 的方法
<input type="submit" value="Subscribe!" th:attr="value=#{subscribe.submit}"/> --设置单个
<img src="../../images/gtvglogo.png" th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" /> --一次设置多个
5.2 设置一些内置的Attribute的方法
<li><a href="product/list.html" th:href="@{/product/list}">Product List</a></li>
<form action="subscribe.html" th:action="@{/subscribe}">
<input type="submit" value="Subscribe!" th:value="#{subscribe.submit}"/>
<img src="../../images/gtvglogo.png" th:src="@{/images/gtvglogo.png}" th:alt-title="#{logo}" /> -- 一次设置多个(alt title)的方法
其它的可用属性:http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#setting-value-to-specific-attributes
5.3 设置html里没有指的任何属性的语法
<span th:whatever="${user.name}">...</span> ---whatever 可以换成任何你想设的属性
六、循环输出的语法
6.1 基本循环
<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>
6.2 循环状态的使用
<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>
关于状态的其它信息的使用详细参考:http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#keeping-iteration-status
七、条件判断
7.1 if 和 unless
<a href="comments.html" th:href="@{/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">view</a>
<a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:if="${not #lists.isEmpty(prod.comments)}">view</a>
7.2 switch 语句
<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> --默认的 case 相当于default
</div>
八、模板 include
8.1 定义和引用代码块
定义代码块
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</div>
</body>
</html>
引用代码块
<body>
...
<div th:insert="~{footer :: copy}"></div>
</body>
引用未用fragment 标注的代码块
<div id="copy-section">
© 2011 The Good Thymes Virtual Grocery
</div>
<body>
...
<div th:insert="~{footer :: #copy-section}"></div>
</body>
8.2 th:insert th:replace th:include 之间的区别
th:insert --- 插入代码块 th:replace -- 替换代码块会替换掉容器标签 th:include ---- 和insert相似但只会插入fragment标注body内的内容。
8.3 带参数的代码段
<div th:fragment="frag (onevar,twovar)">
<p th:text="${onevar} + ' - ' + ${twovar}">...</p>
</div>
<div th:replace="::frag (${value1},${value2})">...</div>
<div th:replace="::frag (onevar=${value1},twovar=${value2})">...</div>
九、局部变量的使用示例
<div th:with="firstPer=${persons[0]}">
<p>
The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.
</p>
</div>
<div th:with="firstPer=${persons[0]},secondPer=${persons[1]}">
<p>
The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.
</p>
<p>
But the name of the second person is
<span th:text="${secondPer.name}">Marcus Antonius</span>.
</p>
</div>
十、注释
<!-- ... -->
十一、说明
以上只列出Thymeleaf了简要常用的语法和使用方式,更多详情的说明和规则请参见:http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#introducing-thymeleaf
基于Spring Boot的Thymeleaf使用
SpringBoot中默认不在支持JSP页面,但它引入了模板框架的使用。我们可以使用模板框架对页面中的内容进行动态绑定
Thymeleaf:一个服务端Java模板引擎,类似于JSP。它为网页的开发工作流程带来优雅的静态模板,它同时可以静态原型来使用。
JSP本质上是Servlet的前端改版,JSP文件在服务器启动时会被转化为一个Servlet来运行,而这个转换过程的效率是十分低的。
Thymeleaf不同于JSP的是它是在HTML文件上进行工作的,我们的模板可以单独作为HTML静态文件运行。模板的外观和功能上依旧类似于HTML,并且模板语法可以被浏览器正确的显示。
引入Thymeleaf
简单的例子:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Welcome Page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<span th:text="${message}">Welcome to Thymeleaf!</span>
</body>
</body>
</html>
不同于原生静态页面,xmlns:th="http://www.thymeleaf.org"并不会对模板页面的生成启任何作用,主要是引入命名空间使得IDE不会对我们的模板语法报错;th:text="${message}为模板语法,用于替换标签所在的文本信息(如果${message}可以取出有效值)
SpringBoot默认是支持Thymeleaf的,我们只需要导入对应的jar包即可:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
如果SpringBoot默认指定的版本不符合我们的需求,我们可以在properties标签中覆盖SpringBoot指定的版本号。具体标签写法可以参考spring-boot-starter-parent的父pomspring-boot-dependencies
导入对应的依赖后,SpringBoot将自动装配模板。并且部分属性配置如下:
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
}
我们可以知道模板默认支持.html文件,在我们控制器中进行跳转时只需返回模板名即可(类似于InternalResourceViewResolver)。并且我们默认以UTF-8编码解析模板
Thymeleaf语法
表达式
Thymeleaf支持多种表达式,如:
变量表达式${...}
选择变量表达式*{...}
链接表达式@{...}
消息表达式#{...}
代码表达式~{...}
${...}等同于OGNL语法,用于从上下文查找指定的值。如获取对象中的属性、调用对象的方法:
/*
* 使用(.)分割属性的层级,获取将调用属性的getter方法
*/
${person.father.name}
/*
* 还可以通过([])的方式获取属性
*/
${person['father']['name']}
/*
* 如果对象是一个map,则点和括号都可以调用map的get(Object key)方法
*/
${countriesByCode.ES}
${personsByName['Stephen Zucchini'].age}
/*
* 如果对象是一个数组,我们可以直接使用在Java中的调用方式
*/
${personsArray[0].name}
/*
* 表达式也可以调用对象的方法,方法可以传入参数
*/
${person.createCompleteName()}
${person.createCompleteNameWithSeparator('-')}
OGNL也提供一些基本的表达式对象,我们可以直接使用#符号引用:
#ctx:上下文对象
#vars:上下文对象
#locale:上下文区域设置
#request:(仅在Web Contexts中)HttpServletRequest对象
#response:(仅在Web上下文中)HttpServletResponse对象
#session:(仅在Web上下文中)HttpSession对象
#servletContext:(仅在Web上下文中)ServletContext对象
我们可以这样得到一些变量:
local country:<span th:text="${#locale.country}">US</span>
实例补充:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#appendix-a-expression-basic-objects
除此之外,OGNL还提供了一组工具对象供我们快速完成常见任务:
#execInfo:有关正在处理的模板谢谢
#message:用于在变量表达式中获取外部化消息的方法,与使用#语法获得的方式相同
#uris:转义URL/URI部分的方法
#conversions:执行配置的转换服务(如果有的话)的方法
#dates:java.util.Date对象的方法:格式化,组件提取等
#calendars:类似于#dates,但对于java.util.Calendar对象
#numbers:用于格式化数字对象的方法
#strings:String对象的方法:contains,startsWith,prepending/appending等
#objects:一般对象的方法
#bools:布尔评估的方法
#arrays:数组的方法
#lists:列表的方法
#sets:集合的方法
#maps:map的方法
#aggregates:在数组或集合上创建聚合的方法
#ids:处理可能重复的id属性的方法(例如:作为迭代的结果)
*{...}大部分功能和${}是一致的,它只是作了一些补充功能:
<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>
当我们在标签中使用th:object获取指定对象时,此时标签内*{}默认选定指定的对象。我们可以直接通过属性名获取值
@{...}用来链接项目中的API,如:
<a href="details.html" th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">view</a>
<!-- 我们也可以使用项目的相对路径 -->
<a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a>
参数用()包围,多个参数用,隔开
{...}可以用于在国际化中显示消息,也可以使用内置对象
~{...}用来插入片段文档,如:
<div th:insert="~{commons :: main}">...</div>
文本
字符串:'one text' , 'another one' , ...
数字:0 , 34 ...
布尔值:true , false ...
空:null
文字标记:one,sometext ...
文本操作
字符串拼接:+
字符替换:|The name is $|
计算操作
二元操作:+ , - , * , / , %
一元操作(负号):-
布尔操作
二元操作:and , or
布尔反转:! , not
比较操作
比较操作:> , < , >= , <= ( gt , lt , ge , le)
判同操作:== , != (eq , ne)
条件操作
if-then:(if) ? (then)
if-then-else:(if) ? (then) : (else)
default:(value) ?: (defalutvalue)
以上的各种操作都是在对html标签属性值的计算。如果我们需要操作html结构,我们需要使用th:*对html文件结构进行操作
Thymeleaf操作
判断操作
<!-- 当表达式成立,该span标签才会显示 -->
<span th:if="判断表达式">1</span>
<!-- 当表达式不成立时,才会显示。与th:if表达式相同,形成if-else -->
<span th:unless="判断表达式">2</span>
模板导入
将代码中重复的代码抽离出来,成为模板文件。我们即可在其他需要使用模板文件的地方引入即可
如:底部模板文件footer.html
<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<body>
<!-- th:fragment指定模板名称,以便调用 -->
<div th:fragment="footer">
<!-- 模板文件结构 -->
</div>
</body>
</html>
当我们在其他文件需要使用到模板结构时,我们可以引入即可
<div th:include="footer::footer"></div>
::前面的footer表示模板所在的文件路径,::后面的footer表示我们在模板文件中指定的模板名称
模板的文件路径也是由Thymeleaf的视图解析器进行解析的,所以默认的路径为classpath:templates/xxx.html
引入模板有以下三种方式:
th:insert:模板片段插入th:insert所在标签内
th:replace:模板片段替换th:replace所在的标签
th:include:模板片段中的内容插入th:include所在的标签内
模板例子:
<footer th:fragment="copy"> © 2011 The Good Thymes Virtual Grocery </footer>
使用三种方式引入模板:
<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div
结果为:
<div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
<div>
© 2011 The Good Thymes Virtual Grocery
</div>
模板在使用的时候是可以传入参数的,可以根据参数模板有不同的显示状态
模板传值:
<footer th:fragment="copy(name)"> [[name]] © 2011 The Good Thymes Virtual Grocery </footer>
使用时:
<div th:insert="footer :: copy(name='zxj')"></div>
文本输出
用来将文本输出到所在标签的内部,而不是属性中
有两种方法输出:
<span th:text="${msg}"></span>
或者
<span th:utext="{msg}"></span>
区别:
两者同样是讲标签中的文本替换,th:text会将替换文本中的特殊字符转义,如hello会渲染成粗体。但th:utext会把替换文本中的字符按原样输出,不会转义
上面两种都属于标签内写法,它也有行内写法。如:
<p>Hello,[[${session.user.name}]]</p>
[[]]等同于th:text,或者
<p>The message is "[(${msg})]"</p>
等同于th:utext
块区域操作
th:block是Thymeleaf唯一一个操作结构块的标签,假设我们有下面一个例子:
<table>
<div th:each="user : ${users}">
<tr>
<td th:text="${user.login}">...</td>
<td th:text="${user.name}">...</td>
</tr>
<tr>
<td colspan="2" th:text="${user.address}">...</td>
</tr>
</div>
</table>
这表示我们将迭代显示div中的内容,但是div的存在对结构有着一定的影响。我们需要迭代多个标签,但是我们又不想添加额外的外层结构。
我们可以使用th:block进行迭代,如:
<table>
<th:block th:each="user : ${users}">
<tr>
<td th:text="${user.login}">...</td>
<td th:text="${user.name}">...</td>
</tr>
<tr>
<td colspan="2" th:text="${user.address}">...</td>
</tr>
</th:block>
</table>
使用这种方式,th:block标签会在迭代完后直接消失的。只会保留标签内部的内容,非常适合迭代多个标签并不添加额外的外层结构
常用的操作
顺序 特点 属性
1 导入模板代码 th:insert、th:replace
2 集合迭代 th:each
3 流程控制 th:if、th:unless、th:switch、th:case
4 本地变量定义 th:object、th:with
5 常规属性修改 th:attr、th:attrprepend、th:attrappend
6 特定属性修改 th:value、th:href、th:src 、...
7 标签内文本修改 th:text、th:utext
8 模板代码定义 th:fragment
9 模板移除 th:remove
出处来自https://heartdream.top/archives/2020020701252332414