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