**Thymeleaf 基本用法总结**
Thymeleaf
- Thymeleaf是一个现代服务器端Java模板引擎,适用于Web和独立环境,能够处理HTML,XML,JavaScript,CSS甚至纯文本。
- Thymeleaf的主要目标是提供一种优雅且高度可维护的模板创建方式。为实现这一目标,它以自然模板的概念为基础,将其逻辑注入模板文件,其方式不会影响模板被用作设计原型。这改善了设计沟通,缩小了设计和开发团队之间的差距。
- Thymeleaf也从一开始就设计了Web标准 - 特别是HTML5 - 允许您创建完全验证的模板,如果您需要的话。
- 前后端分离,独立于服务器。
引用命名空间
<html xmlns:th="http://www.thymeleaf.org">
在html中引入此命名空间,可避免编辑器出现html验证错误,虽然加不加命名空间对Thymeleaf的功能没有任何影响。
标准表达式
· 简单表达式 (simple expressions)
${...} 变量表达式
*{...} 选择变量表达式
#{...} 消息表达式
@{...} 链接url表达式
· 字面量
'one text','another one!',... 文本
0,34,3.0,12.3,... 数值
true false 布尔类型
null 空
one,sometext,main 文本字符
· 文本操作
+ 字符串连接
|The name is ${name}| 字符串连接
· 算术运算
+ , - , * , / , % 二元运算符
- 负号(一元运算符)
· 布尔操作
and,or 二元操作符
!,not 非(一元操作符)
· 关系操作符
> , < , >= , <= (gt , lt , ge , le)
== , != (eq, ne)
· 条件判断
(if) ? (then) if-then
(if) ? (then) : (else) if-then-else
链接URL
URL是Web应用程序模板中的一等公民,而Thymeleaf标准方言具有特殊的语法,@语法:@{…}
不同类型的网址:
1.绝对网址: http://www.thymeleaf.org
2.相对URL,可以是:
页面相对: user/login.html
上下文相关:( /itemdetails?id=3服务器中的上下文名称将自动添加)
服务器相对:( ~/billing/processInvoice允许在同一服务器中的另一个上下文(=应用程序)中调用URL)。
协议相对URL: //code.jquery.com/jquery-2.0.3.min.js
引入js与css
使用thymeleaf,当未连接服务器时,使用的是本地的连接href="",当应用thymeleaf时,使用的是th:href="",th:href会直接将本地数据替换,实现前后端的分离。
<link rel="stylesheet" th:href="@{/static/css/bootstrap.min.css}" href="../static/css/bootstrap.min.css" />
<script src="../js/jquery-3.3.1.min.js" th:src="@{/js/jquery-3.3.1.min.js}"></script>
现在大多都是使用html5,有时th:src和th:href会报错,对h5不友好,因此可以使用data-th-href
<link rel="stylesheet" data-th-href="@{/static/css/bootstrap.min.css}" />
<script src="../js/jquery-3.3.1.min.js" data-th-src="@{/js/jquery-3.3.1.min.js}"></script>
在其他文件引入head部分
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="header">
<meta charset="UTF-8" />
<title th:text="#{head.title}"></title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" data-th-href="@{/static/css/bootstrap.min.css}" />
<script src="../js/jquery-3.3.1.min.js" data-th-src="@{/js/jquery-3.3.1.min.js}"></script>
</head>
在要引用的页面 引入
他就相当于jsp 中我们常用的<%@ include file="/WEB-INF/jsp/public/header.jspf"%>
<head th:include="theme/fragments::header" />
a标签
<!-- 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 href="product/list.html" th:href="@{/product/list}">Product List</a>
img标签
<img src="../../images/logo.png" th:src="@{/images/logo.png}" th:title="#{logo}" th:alt="#{logo}" />
img标签一次设置多个值,等同于
<img src="../../images/logo.png" th:attr="src=@{/images/logo.png},title=#{logo},alt=#{logo}" />
获取变量值
文本输出
1.固定文字内容
<p>The year is <span th:text="2018">2019</span>.</p>
<p>
Now you are looking at a <span th:text="'working web application'">template file</span>.
</p>
2.连接服务器内容
<p>
hello
<span th:text="${name}">name</span>
</p>
3.文本拼接
<span th:text="|Welcome to our application, ${user.name}!|">
<span th:text="'Welcome to our application, ' + ${user.name} + '!'">
算术运算
算术运算:+,-,*,/和%
<div th:with="isEven=(${prodStat.count} % 2 == 0)">
<div th:with="isEven=${prodStat.count % 2 == 0}">
条件表达式
<tr th:class="${row.even}? 'even' : 'odd'">
...
</tr>
<tr th:class="${row.even}? (${row.first}? 'first' : 'even') : 'odd'">
...
</tr>
条件判断
1.a标签只有在th:if的情况下显示
<a th:if="${myself=='yes'}" > </i> </a>
2.unless与if正好相反
<a th:unless=${session.user != null} th:href="@{/login}" >Login</a>
迭代(for循环)
<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>
保持迭代的状态
使用时th:each,Thymeleaf提供了一种机制,可用于跟踪迭代的状态:状态变量。
状态变量在th:each属性中定义,包含以下数据:
当前迭代索引,从0开始。这是index属性。
当前迭代索引,从1开始。这是count属性。
迭代变量中元素的总量。这是size酒店。
每次迭代的iter变量。这是current酒店。
当前迭代是偶数还是奇数。这些是even/odd布尔属性。
当前迭代是否是第一个。这是first布尔属性。
当前迭代是否是最后一次。这是last布尔属性。
<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>
状态变量(iterStat在此示例中)在th:each属性中通过在iter变量本身之后写入其名称来定义,用逗号分隔。就像iter变量一样,status变量的范围也是由持有该th:each属性的标记定义的代码片段。
切换语句(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>
</div>
模版布局
<div th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</div>
在需要引入的页面
<div th:insert="~{footer :: copy}"></div>
<!-- 相当于 -->
<div th:insert="footer :: copy"></div>
th:insert和th:replace(和th:include)之间的区别
th:insert 是最简单的:它只是插入指定的片段作为其主机标签的主体。
th:replace实际上用指定的片段替换它的主机标签。
th:include类似于th:insert,但不是插入片段,它只插入此片段的内容。
<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>
内联
表达式内联
<p>Hello, [[${session.user.name}]]!</p>
相当于
<p>Hello, <span th:text="${session.user.name}">Sebastian</span>!</p>
优点
当你静态打开它们时,内联表达式将逐字显示在你的HTML文件中,所以你可能无法将它们用作设计原型了!
浏览器显示的将会是
Hello, [[${session.user.name}]]!
在设计实用性方面非常清楚。
禁用内联
可以禁用此机制,因为实际上可能存在我们确实希望输出[[…]]或[(…)]序列而不将其内容作为表达式处理的情况。为此,我们将使用th:inline=“none”:
<p th:inline="none">A double array looks like this: [[1, 2, 3], [4, 5]]!</p>
文字内联
文本内联与我们刚刚看到的表达内联功能非常相似,但它实际上增加了更多功能。必须明确启用它th:inline=“text”。
JavaScript内联
JavaScript内联允许
<script th:inline="javascript">
...
var username = [(${session.user.name})];
...
</script>
js附加代码:
/*[+
var msg = 'This is a working application';
+]*/
js移除代码:
/*[- */
var msg = 'This is a non-working template';
/* -]*/
CSS内联
<style th:inline="css">
...
</style>
<style th:inline="css">
.[[${classname}]] {
text-align: [[${align}]];
}
</style>
表达式实用程序对象
dates : java.util.Date的功能方法类。
calendars : 类似#dates,面向java.util.Calendar
numbers : 格式化数字的功能方法类
strings : 字符串对象的功能类,contains,startWiths,prepending/appending等等。
objects: 对objects的功能类操作。
bools: 对布尔值求值的功能方法。
arrays:对数组的功能类方法。
lists: 对lists功能类方法
sets
maps
常用例子
${#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.day(date)} // also arrayDay(...), listDay(...), etc.
${#dates.month(date)} // also arrayMonth(...), listMonth(...), etc.
${#dates.monthName(date)} // also arrayMonthName(...), listMonthName(...), etc.
${#dates.monthNameShort(date)} // also arrayMonthNameShort(...), listMonthNameShort(...), etc.
${#dates.year(date)} // also arrayYear(...), listYear(...), etc.
${#dates.dayOfWeek(date)} // also arrayDayOfWeek(...), listDayOfWeek(...), etc.
${#dates.dayOfWeekName(date)} // also arrayDayOfWeekName(...), listDayOfWeekName(...), etc.
${#dates.dayOfWeekNameShort(date)} // also arrayDayOfWeekNameShort(...), listDayOfWeekNameShort(...), etc.
${#dates.hour(date)} // also arrayHour(...), listHour(...), etc.
${#dates.minute(date)} // also arrayMinute(...), listMinute(...), etc.
${#dates.second(date)} // also arraySecond(...), listSecond(...), etc.
${#dates.millisecond(date)} // also arrayMillisecond(...), listMillisecond(...), etc.
<span th:text="${#calendars.format(today,'dd MMMM yyyy')}">13 May 2011</span>
常用th标签
标签 | 说明 | 例子 |
---|---|---|
th:id | 替换id | <input th:id="'xxx' + ${collect.id}"/> |
th:text | 文本替换 | <p th:text="${collect.description}">description</p> |
th:utext | 支持html的文本替换 | <p th:utext="${htmlcontent}">conten</p> |
th:object | 替换对象 | <div th:object="${session.user}"> |
th:value | 属性赋值 | <input th:value="${user.name}" /> |
th:with | 变量赋值运算 | <div th:with="isEven=${prodStat.count}%2==0"></div> |
th:style | 设置样式 | th:style="'display:' + @{(${sitrue} ? 'none' : 'inline-block')} + ''" |
th:onclick | 点击事件 | th:onclick="'getCollect()'" |
th:each | 属性赋值 | tr th:each="user,userStat:${users}"> |
th:if | 判断条件 | <a th:if="${userId == collect.userId}" > |
th:unless | 和th:if判断相反 | <a th:href="@{/login}" th:unless=${session.user != null}>Login</a> |
th:href | 链接地址 | <a th:href="@{/login}" th:unless=${session.user != null}>Login</a> /> |
th:switch | 多路选择 配合th:case 使用 | <div th:switch="${user.role}"> |
th:case | th:switch的一个分支 | <p th:case="'admin'">User is an administrator</p> |
th:fragment | 布局标签,定义一个代码片段,方便其它地方引用 | <div th:fragment="alert"> |
th:include | 布局标签,替换内容到引入的文件 | <head th:include="layout :: htmlhead" th:with="title='xx'"></head> |
th:replace | 布局标签,替换整个标签到引入的文件 | <div th:replace="fragments/header :: title"></div> |
th:selected | selected选择框 选中 | th:selected="(${xxx.id} == ${configObj.dd})" |
th:src | 图片类地址引入 | <img class="img-responsive" alt="App Logo" th:src="@{/img/logo.png}" /> |
th:inline | 定义js脚本可以使用变量 | <script type="text/javascript" th:inline="javascript"> |
th:action | 表单提交的地址 | <form action="subscribe.html" th:action="@{/subscribe}"> |
th:remove | 删除某个属性 | <tr th:remove="all"> 1.all:删除包含标签和所有的孩子。2.body:不包含标记删除,但删除其所有的孩子。3.tag:包含标记的删除,但不删除它的孩子。4.all-but-first:删除所有包含标签的孩子,除了第一个。5.none:什么也不做。这个值是有用的动态评估。 |
th:attr | 设置标签属性,多个属性可以用逗号分隔 | 比如<p th:attr="src=@{/image/aa.jpg},title=${title}"> 内容,这样如果${title}=’这个是title’ 则结果就是<p src="/image/aa.jpg" title="这个是title">内容</p> |
总结
1.thymeleaf适用于与后端交互较多的应用。
2.前后端独立开发。
3.未连接服务器的时候,也能很好的展示页面。