模板解读
- 上一篇中使用的渲染语句为
<p th:text="${description}">这里显示的是 description 字段内容</p>
- 前半部分 <p> 为 html 的标签
- 后半部分是 Thymeleaf 属性标签和表达式语法
- th:text 表示文本替换、${description}表示读取后台设置的 description 字段,该模板文件语句的作用就是动态的将 p 标签中的内容替换为 description 字段内容,如果是写在 <div></div> 标签中的话也是修改其中的内容。
同时该语句也展示了 Thymeleaf 模板文件的编写规则:
- 任意的 Thymeleaf 属性标签 th:* 需要写在 html 标签体中( th:block 除外 )
- Thymeleaf 表达式写在 Thymeleaf 属性标签中
thymeleaf 设置属性
th:* 属性
-
th:text 对应的是 HTML5 中的 text 属性,除 th:text 属性外,Thymeleaf 也提供了其他的标签属性来替换 HTML5 原生属性的值,属性节选如下:
-
th:background 对应 HTML5 中的背景属性
-
th:class 对应 HTML5 中的 class 属性
-
th:href 对应 HTML5 中的链接地址属性
-
th:id 和 th:name 分别对应 HTML5 中的 id 和 name 属性…
-
th:block 比较特殊,它是 Thymeleaf 提供的唯一的一个 Thymeleaf 块级元素,其特殊性在于 Thymeleaf 模板引擎在处理<th:block>的时候会删掉它本身,而保留其内容。
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymeleaf setting-value-to-specific-attributes</title>
</head>
<!--background 标签-->
<body th:background="${th_background}" background="D0D0D0">
<!--text 标签-->
<h1 th:text="${title}">html标签演示</h1>
<div>
<h5>id、name、value标签:</h5>
<!-- id name value 标签-->
<input id="input1" name="input2" value="1" th:id="${th_id}" th:name="${th_name}" th:value="${th_value}"/>
</div>
<br/>
<div class="div1" th:class="${th_class}">
<h5>class href 标签</h5>
<!-- class href 标签-->
<a th:href="${th_href}" href="https://www.bilibili.com">链接地址</a>
</div>
</body>
</html>
@GetMapping("/attributes")
public String attributes(ModelMap map){
//change text of h1
map.put("title","Thymeleaf 标签演示");
//change id name value
map.put("th_id", "thymeleaf-input");
map.put("th_name", "thymeleaf-input");
map.put("th_value", "12");
//change class href
map.put("th_class","thymeleaf-class");
map.put("th_href","http://www.baidu.com");
return"attributes";
}
Thymeleaf语法规则
-
表达式语法
- 变量表达式: ${…}
- 选择变量表达式: *{…}
- 信息表达式: #{…}
- 链接 URL 表达式: @{…}
- 分段表达式: ~{…}
-
字面量
- 字符串: ‘one text’, ‘Another one!’ …
- 数字: 0, 34, 3.0, 12.3 …
- 布尔值: true, false
- Null 值: null
- 字面量标记:one, sometext, main …
-
文本运算
- 字符串拼接: +
- 字面量置换: |The name is ${name}|
-
算术运算
- 二元运算符: +, -, *, /, %
- 负号(一元运算符): (unary operator): -
-
布尔运算
- 二元运算符: and, or
- 布尔非(一元运算符): !, not
-
比较运算
- 比较: >, <, >=, <= (gt, lt, ge, le)
- 相等运算符: ==, != (eq, ne)
- 比较运算符也可以使用转义字符,比如大于号,可以使用 Thymeleaf 语法 gt 也可以使用转义字符 >
-
条件运算符
- If-then: (if) ? (then)
- If-then-else: (if) ? (then) : (else)
- 4666Default: (value) ?: (defaultvalue)
-
特殊语法
- 无操作: _
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>thymeleaf simple syntax</title>
</head>
<body>
<h1>Thymeleaf 简单语法</h1>
<div>
<h5>基本操作类型(字符串):</h5>
<p>一个简单的字符串:<span th:text="'Thymeleaf Text'"> default text </span>.</p>
<p>“+”字符串连接:<span th:text="'Thymeleaf text contact,' + ${thymeleafText}">default text</span>. </p>
<p>“|”字符串连接:<span th:text="|Thymeleaf text contact,${thymeleafText}|">default text</span>. </p>
</div>
<div>
<h5>基本操作类型(数字):</h5>
<p>一个简单神奇的数字:<span th:text="2021"> 1000 </span>.</p>
<p>算术运算: 2021 + 1 = <span th:text="${number1}+1"> 0</span>.</p>
<p>算术运算: 14 - 1 = <span th:text="14-1">0</span>.</p>
<p>算术运算:673 * 3 = <span th:text="673*${number2}">0</span>.</p>
<p>算术运算:39 ÷ 3 = <span th:text="39/3">0</span>. </p>
</div>
<div>
<h5>基本操作类型(布尔值):</h5>
<p>简单数字的比较: 2021 > 2020 = <span th:text="2021>2020"> unknown </span>.</p>
<p>字符串比较:thymeleafText == 'rick' <span th:text="${thymeleafText} == 'rick'">unknown</span>.</p>
<p>数字比较:13 == 39/3 <span th:text="13 == 39/3"> unknown</span>.</p>
</div>
</body>
</html>
@GetMapping("/simple")
public String simple(ModelMap map){
map.put("thymeleafText", "rick");
map.put("number1", "2021");
map.put("number2", "3");
return "simple";
}
表达式语法
- 表达式包括:变量表达式 ${…}、选择变量表达式 *{…}、信息表达式 #{…}、链接 URL 表达式:@{…}、分段表达式: ~{…},这些表达式一般只能写在 Thymeleaf 模板文件的 th 标签内,不然不会生效,表达式语法的主要作用就是获取变量值、获取绑定对象的变量值、国际化变量取值、URL 拼接与生成、 Thymeleaf 模板布局
变量表达式
- 变量表达式即 OGNL 表达式或 Spring EL 表达式,
用于获取模板中与后端返回数据所绑定对象的值,
写法为 ${}
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
<meta charset="UTF-8" >
<title th:text="${title}">语法测试</title>
</head>
<body>
<h3>#strings 工具类测试</h3>
<div th:if="${not #strings.isEmpty(testString)}">
<p>testString 初始值:<span th:text="${testString}"></span> </p>
<p>toUpperCase: <span th:text="${#strings.toUpperCase(testString)}"></span> </p>
<p>toLowerCase: <span th:text="${#strings.toLowerCase(testString)}"></span> </p>
<p>忽略大小写的对比 equalsIgnoreCase: <span th:text="${#strings.equalsIgnoreCase(testString,'ThYmeLeaf')}"></span> </p>
<p>字符位置 indexOf: <span th:text="${#strings.indexOf(testString,'l')}"></span> </p>
<p>subString: <span th:text="${#strings.substring(textString,1,3)}"></span></p>
<p>startsWith: <span th:text="${#strings.startsWith(testString,'Thyme')}"></span></p>
<p>contains: <span th:text="${#strings.contains(testString,'leAf')}"></span></p>
</div>
<h3>#boolean 工具类测试</h3>
<!--如果Boolean==false则不显示-->
<div th:if="${#bools.isTrue(bool)}">
<p th:text="${bool}"></p>
</div>
<h3>#arrays 工具类测试</h3>
<div th:if="${not #arrays.isEmpty(testArray)}">
<p>size:<span th:text="${#arrays.length(testArray)}"></span></p>
<p>contains 4?:<span th:text="${#arrays.contains(testArray,4)}"></span></p>
<p>containsAll :<span th:text="${#arrays.containsAll(testArray,testArray)}"></span></p>
<p>循环读取 :<span th:each="i:${testArray}" th:text="${i+' '}"></span></p>
</div>
<h3>#lists 工具类测试</h3>
<div th:unless = "${#lists.isEmpty(testLists)}">
<p>size:<span th:text="${#lists.size(testLists)}" ></span></p>
<p>contains:<span th:text="${#lists.contains(testLists,2)}"></span> </p>
<p>sort: <span th:text="${#lists.sort(testLists)}"></span> </p>
<p>循环读取:<span th:each="i:${testLists}" th:text="${i+''}"></span></p>
</div>
<h3>#maps 工具类测试</h3>
<div th:if="${not #maps.isEmpty(testMap)}">
<p>size: <span th:text="${#maps.size(testMap)}"></span></p>
<p>containsKey:<span th:text="${#maps.containsKey(testMap,'platform')}"></span> </p>
<p>containsKey:<span th:text="${#maps.containsValue(testMap,'13')}"></span> </p>
<p>读取map中键为title的值:<span th:if="${#maps.containsKey(testMap,'title')}" th:text="${testMap.get(title)}"></span></p>
</div>
<h3>#dates 工具类测试</h3>
<div>
<p>year: <span th:text="${#dates.year(testDate)}"></span></p>
<p>month: <span th:text="${#dates.month(testDate)}"></span></p>
<p>day: <span th:text="${#dates.day(testDate)}"></span></p>
<p>hour: <span th:text="${#dates.hour(testDate)}"></span></p>
<p>minute: <span th:text="${#dates.minute(testDate)}"></span></p>
<p>second: <span th:text="${#dates.second(testDate)}"></span></p>
<p>格式化: <span th:text="${#dates.format(testDate)}"></span></p>
<p>yyyy-MM-dd HH:mm:ss格式化: <span th:text="${#dates.format(testDate,'yyyy-MM-dd HH:mm:ss')}"></span></p>
</div>
</body>
</html>
controller
@GetMapping("/test")
public String test(ModelMap map){
map.put("title","Thymeleaf 语法测试");
map.put("testString","Thymeleaf");
map.put("bool",true);
map.put("testArray",new Integer[]{2018,2019,2020,2021});
map.put("testList", Arrays.asList("Spring","Thymeleaf","Spring Boot","Java"));
Map testMap = new HashMap();
testMap.put("platform","juejin");
testMap.put("title","Spring Boot Mall");
testMap.put("author","Nice");
map.put("testMap",testMap);
map.put("testDate", new Date());
return "test";
}
输出
#strings 工具类测试
testString 初始值:Thymeleaf
toUpperCase: THYMELEAF
toLowerCase: thymeleaf
忽略大小写的对比 equalsIgnoreCase: true
字符位置 indexOf: 5
subString:
startsWith: true
contains: false
#boolean 工具类测试
true
#arrays 工具类测试
size:4
contains 4?:false
containsAll :true
循环读取 :2018 2019 2020 2021
#lists 工具类测试
#maps 工具类测试
size: 3
containsKey:true
containsKey:false
读取map中键为title的值:
#dates 工具类测试
year: 2021
month: 4
day: 18
hour: 21
minute: 22
second: 42
格式化: 2021年4月18日 下午09时22分42秒
yyyy-MM-dd HH:mm:ss格式化: 2021-04-18 21:22:42