https://segmentfault.com/a/1190000009903821
Thymeleaf 目前最新版本3.0
Thymeleaf作为Spring-Boot官方推荐模板引擎,而且支持纯HTML浏览器展现(模板表达式在脱离运行环境下不污染html结构).是时候了解一番了。与Spring集成
<dependency>
<groupId>org.thymeleafgroupId>
<artifactId>thymeleaf-spring4artifactId>
<version>3.0.0.RELEASEversion>
dependency>
与Spring-Boot集成:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
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这个类,上面的配置实际上就是注入到该类中的属性值.
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>hellotitle>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
head>
<body>
<p th:text="'Hello!, ' + ${name} + '!'" >3333p>
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
可以看出获取变量值用$符号,对于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}">Sebastianspan>.p>
<p>Surname: <span th:text="*{lastName}">Pepperspan>.p>
<p>Nationality: <span th:text="*{nationality}">Saturnspan>.p>
div>
//等价于
<div>
<p>Name: <span th:text="${session.user.firstName}">Sebastianspan>.p>
<p>Surname: <span th:text="${session.user.lastName}">Pepperspan>.p>
<p>Nationality: <span th:text="${session.user.nationality}">Saturnspan>.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 th:with="firstPer=${persons[0]}">
<p>
The name of the first person is <span th:text="${firstPer.name}">Julius Caesarspan>.
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 Caesarspan>.
p>
<p>
But the name of the second person is
<span th:text="${secondPer.name}">Marcus Antoniusspan>.
p>
div>
2.引入URL
Thymeleaf对于URL的处理是通过语法@{…}
来处理的
<a th:href="@{http://blog.csdn.net/u012706811}">绝对路径
<a th:href="@{/}">相对路径
<a th:href="@{css/bootstrap.min.css}">Content路径,默认访问static下的css文件夹
类似的标签有:th:href和th:src
<a href="details.html"
th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">viewa>
<a href="details.html" th:href="@{/order/details(orderId=${o.id})}">viewa>
<a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">viewa>
<a th:href="@{${url}(orderId=${o.id})}">viewa>
<a th:href="@{'/details/'+${user.login}(orderId=${o.id})}">viewa>
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
Switch
Thymeleaf同样支持多路选择Switch结构,默认属性default可以用*表示:
<div th:switch="${user.role}">
<p th:case="'admin'">User is an administrator
<p th:case="#{roles.manager}">User is a manager
<p th:case="*">User is some other thing
5.循环
<tr th:each="prod : ${prods}">
<td th:text="${prod.name}">Onions
<td th:text="${prod.price}">2.41
<td th:text="${prod.inStock}? #{true} : #{false}">yes
迭代对象必须为
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 th:text="${prod.price}">2.41
<td th:text="${prod.inStock}? #{true} : #{false}">yes
//不过也可以直接加Stat后缀访问状态变量
<tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'">
<td th:text="${prod.name}">Onions
<td th:text="${prod.price}">2.41
<td th:text="${prod.inStock}? #{true} : #{false}">yes
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'">
模板变化
推荐你去掉模板中的 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}]];
Thymeleaf 3.0 引入了一个新的片段表达式。形如:~{commons::footer}。
该特性十分有用(比如解决定义通用的header和footer的问题)
base.html
<head th:fragment="common_header(title,links)">
<title th:replace="${title}">The awesome applicationtitle>
<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>
<th:block th:replace="${links}" />
head>
main.html
<head th:replace="base :: common_header(~{::title},~{::link})">
<title>Awesome - Maintitle>
<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}">...
~{::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)标记,下划线”_”,代表什么也不做。
例如:no user authenticated
当user.name 为空的时候,直接输出标签体中的内容
普通html注释:
Thymeleaf 注释:
1、
2、
<div>
you can see me only before Thymeleaf processes me!
div>
3、
//不会转义时
<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>
http://www.thymeleaf.org/doc/...
https://github.com/jmiguelsam...
https://github.com/jmiguelsam...
https://github.com/jmiguelsam...
https://github.com/tengj/Spri...
参考:
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/...