Thymeleaf 目前最新版本3.0
Thymeleaf作为Spring-Boot官方推荐模板引擎,而且支持纯HTML浏览器展现(模板表达式在脱离运行环境下不污染html结构).是时候了解一番了。
安装与初始化配置
与Spring集成
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>3.0.0.RELEASE</version>
</dependency>
与Spring-Boot集成:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
在Spring中进行配置:
@Configuration
@EnableWebMvc
@ComponentScan("com.thymeleafexamples")
public class ThymeleafConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware {
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Bean
public ViewResolver viewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
@Bean
public TemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setEnableSpringELCompiler(true);
engine.setTemplateResolver(templateResolver());
return engine;
}
private ITemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(applicationContext);
resolver.setPrefix("/WEB-INF/templates/");
resolver.setTemplateMode(TemplateMode.HTML);
return resolver;
}
}
在Spring-Boot中只需如下配置:
#thymeleaf start
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
#开发时关闭缓存,不然没法看到实时页面
spring.thymeleaf.cache=false
#thymeleaf end
具体可以配置的参数可以查看 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties这个类,上面的配置实际上就是注入到该类中的属性值.
基本语法
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<!--/*@thymesVar id="name" type="java.lang.String"*/-->
<p th:text="'Hello!, ' + ${name} + '!'" >3333</p>
</body>
</html>
表达式
Variable Expressions: ${…}
Selection Variable Expressions: *{…}
Message Expressions: #{…}
Link URL Expressions: @{…}
Fragment Expressions: ~{…}
字符串操作:
String concatenation: +
Literal substitutions: |The name is ${name}|
条件操作:
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
No-Operation: _
如:'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))
1、获取变量值
<p th:text="'Hello!, ' + ${name} + '!'" >3333</p>
可以看出获取变量值用$符号,对于javaBean的话使用变量名.属性名方式获取,这点和EL表达式一样.另外$表达式只能写在th标签内部,不然不会生效#{}
是国际化支持取值的符号
注意:th:text与th:utext的区别,输出中文时应该使用th:utext
${..}实际语法是:OGNL(非web),SpEL(web) ,支持的内置变量
便捷部分
${x} will return a variable x stored into the Thymeleaf context or as a request attribute.
${param.x} will return a request parameter called x (which might be multivalued).
${session.x} will return a session attribute called x.
${application.x} will return a servlet context attribute called x.
基本的
#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.
工具对象
#execInfo: information about the template being processed.
#messages: methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.
#uris: methods for escaping parts of URLs/URIs
#conversions: methods for executing the configured conversion service (if any).
#dates: methods for java.util.Date objects: formatting, component extraction, etc.
#calendars: analogous to #dates, but for java.util.Calendar objects.
#numbers: methods for formatting numeric objects.
#strings: methods for String objects: contains, startsWith, prepending/appending, etc.
#objects: methods for objects in general.
#bools: methods for boolean evaluation.
#arrays: methods for arrays.
#lists: methods for lists.
#sets: methods for sets.
#maps: methods for maps.
#aggregates: methods for creating aggregates on arrays or collections.
#ids: methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).
工具对象的使用方式见:http://www.thymeleaf.org/doc/…, 以下仅仅举几个例子
${#dates.format(date, 'dd/MMM/yyyy HH:mm')}
${#dates.arrayFormat(datesArray, 'dd/MMM/yyyy HH:mm')}
${#dates.listFormat(datesList, 'dd/MMM/yyyy HH:mm')}
${#dates.setFormat(datesSet, 'dd/MMM/yyyy HH:mm')}
${#dates.createNow()}
${#dates.createToday()} //time set to 00:00
${#strings.isEmpty(name)} //Check whether a String is empty (or null)
${#strings.arrayIsEmpty(nameArr)}
${#strings.listIsEmpty(nameList)}
${#strings.setIsEmpty(nameSet)}
${#strings.startsWith(name,'Don')} // also array*, list* and set*
${#strings.endsWith(name,endingFragment)} // also array*, list* and set*
${#strings.length(str)}
${#strings.equals(str)}
${#strings.equalsIgnoreCase(str)}
${#strings.concat(str)}
${#strings.concatReplaceNulls(str)}
用*{...}
选择对象里的变量,如
<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>
字面量
Text literals: ‘one text’, ‘Another one!’,…
Number literals: 0, 34, 3.0, 12.3,…
Boolean literals: true, false
Null literal: null
字符串一般需要包围在’单引号内,但也有几种变通方式
<div th:class="'content'">...</div>
<span th:text="|Welcome to our application, ${user.name}!|">
//Which is equivalent to:
<span th:text="'Welcome to our application, ' + ${user.name} + '!'">
<span th:text="${onevar} + ' ' + |${twovar}, ${threevar}|">
定义模板本地变量
<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>
2.引入URL
Thymeleaf对于URL的处理是通过语法@{…}
来处理的
<a th:href="@{http://blog.csdn.net/u012706811}">绝对路径</a>
<a th:href="@{/}">相对路径</a>
<a th:href="@{css/bootstrap.min.css}">Content路径,默认访问static下的css文件夹</a>
类似的标签有:th:href和th:src
<!-- 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>
<a th:href="@{${url}(orderId=${o.id})}">view</a>
<a th:href="@{'/details/'+${user.login}(orderId=${o.id})}">view</a>
Server root relative URLs
An additional syntax can be used to create server-root-relative (instead of context-root-relative) URLs in order to link to different contexts in the same server. These URLs will be specified like @{~/path/to/something}
3、运算符
在表达式中可以使用各类算术运算符,例如+, -, *, /, %
th:with="isEven=(${prodStat.count} % 2 == 0)"
逻辑运算符>, <, >=, <=,==,!= (gt, lt, ge, le,eq,ne)都可以使用,唯一需要注意的是使用<,>时需要用它的HTML转义符:
th:if="${prodStat.count} > 1"
th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')"
布尔运算符: and or not/!
4.条件
if/unless
Thymeleaf中使用th:if和th:unless属性进行条件判断,标签只有在th:if中条件成立时才显示,th:unless于th:if恰好相反,只有表达式中的条件不成立,才会显示其内容。
<a th:href="@{/login}" th:unless=${session.user != null}>Login</a>
Switch
Thymeleaf同样支持多路选择Switch结构,默认属性default可以用*表示:
<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>
</di
5.循环
<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>
迭代对象必须为
Any object implementing
java.util.Iterable、 java.util.Enumeration、java.util.Iterator
Any object implementing java.util.Map. When iterating maps, iter variables will be of class
java.util.Map.Entry
.Any array.
Any other object will be treated as if it were a single-valued list containing the object itself.
<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>
//不过也可以直接加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>
th:each内置迭代状态属性:
index ,当前索引,从0开始。
count,当前数目,从1开始。
size,总大小
current,当前值
even/odd boolean properties.
first boolean property.
last boolean property.
6、设置html标签属性
<img src="../../images/gtvglogo.png"
th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />
//which is equivalent:
<img src="../../images/gtvglogo.png"
th:src="@{/images/gtvglogo.png}" th:title="#{logo}" th:alt="#{logo}" />
//append
<tr th:each="prod : ${prods}" class="row" th:classappend="${prodStat.odd}? 'odd'">
Thymeleaf 3中的一些变化和特性
模板变化
推荐你去掉模板中的 th:inline=“text” 属性。因为在HTML或XML模板中,不再需要该属性去支持文本中内联表达式的特性。完整的HTML5 标记支持
不在强制要求标签闭合,属性加引号等等模板类型
Thymeleaf 3 移除了之前版本的模板类型,新的模板类型为:HTML、XML、TEXT、JAVASCRIPT、CSS、RAW
文本型模板
文本型模板使得Thymeleaf可以支持输出CSS、Javascript和文本文件。在你想要在CSS或Javascript文件中使用服务端的变量时;或者想要输出纯文本的内容时。
在文本模式中使用Thymeleaf的特性,你需要使用一种新的语法,例如:
[# th:each="item : ${items}"]
- [# th:utext="${item}" /]
[/]
var a = [# th:text="${msg}"/];
增强的内联机制
现在可无需额外的标签,直接在文本中输出数据:
This product is called [[${product.name}]] and it's great!
var a = [[${msg}]];
4、片段(Fragment)表达式
Thymeleaf 3.0 引入了一个新的片段表达式。形如:~{commons::footer}。
该特性十分有用(比如解决定义通用的header和footer的问题)
base.html
<head th:fragment="common_header(title,links)">
<title th:replace="${title}">The awesome application</title>
<!-- Common styles and scripts -->
<link rel="stylesheet" type="text/css" media="all" th:href="@{/css/awesomeapp.css}">
<link rel="shortcut icon" th:href="@{/images/favicon.ico}">
<script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"></script>
<!--/* Per-page placeholder for additional links */-->
<th:block th:replace="${links}" />
</head>
main.html
<head th:replace="base :: common_header(~{::title},~{::link})">
<title>Awesome - Main</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}">
</head>
片段经常和th:insert or th:replace
一起使用
<div th:insert="~{commons :: main}">...</div>
<div th:with="frag=~{footer :: #main/text()}">
<p th:insert="${frag}">
</div>
~{::selector} or ~{this::selector}
引用本模板内的片段
不使用th:fragment定义的片段的情况:
<div id="copy-section">
© 2011 The Good Thymes Virtual Grocery
</div>
<div th:insert="~{footer :: #copy-section}"></div>
th:insert and th:replace (and th:include)
的区别:
th:insert 插入片段本身
th:replace actually replaces its host tag with the specified fragment.
th:include 与th:insert不同的是,它插入的是片段解析后的内容
5、无操作标记(token)
Thymeleaf 3.0 另一个新的特性就是无操作(NO-OP no-operation)标记,下划线”_”,代表什么也不做。
例如:<span th:text="${user.name} ?: _">no user authenticated</span>
当user.name 为空的时候,直接输出标签体中的内容
注释
普通html注释:<!– User info follows –>
Thymeleaf 注释:
1、<!--/* This code will be removed at Thymeleaf parsing time! */-->
2、<!--/*-->
<div>
you can see me only before Thymeleaf processes me!
</div>
<!--*/-->
3、<!--/*/
<div th:text="${...}">
...
</div>
/*/-->
html内联
//不会转义时
<p>The message is "[(${msg})]"</p>
//等价于
<p>The message is "This is <b>great!</b>"</p>
//转义时
<p>The message is "[[${msg}]]"</p>
//等价于
<p>The message is "This is <b>great!</b>"</p>
//禁用内联
<p th:inline="none">A double array looks like this: [[1, 2, 3], [4, 5]]!</p>
//js内联
<script th:inline="javascript">
...
var username = [[${session.user.name}]];
...
</script>
//css内联
<style th:inline="css">
.[[${classname}]] {
text-align: [[${align}]];
}
</style>
Markup Selector Syntax
http://www.thymeleaf.org/doc/…
demo:
参考:
http://www.thymeleaf.org/doc/…
http://www.thymeleaf.org/doc/…
http://blog.csdn.net/u0127068…
https://www.tianmaying.com/tu…
http://www.thymeleaf.org/doc/…