1. 简单表达式

1.1 外部化文本 #{---}

外部化文本是从模板文件中提取模板代码的片段,以便它们可以保存在单独的文件(通常为 .properties 文件)中,并且可以轻松地替换为使用其他语言编写的等效文本(称为国际化或简单的i18n) 。文本的外部化片段通常称为“消息(messages)”。

  1. <p th:text="#{home.welcome}">Welcome to our grocery store!</p>

1.2 变量表达式 ${---}

变量表达式有丰富的内置方法,使其更强大,更方便。

1.2.1 变量表达式功能

  1. 1)可以获取对象的属性和方法
  2. 2)可以使用ctxvarslocalerequestresponsesessionservletContext内置对象
  3. 3)可以使用datesnumbersstringsobjectsarrayslistssetsmaps等内置方法(重点介绍)

1.2.2 常用的内置对象

  1. #ctx:上下⽂对象。
  2. #vars:上下⽂变量。
  3. #locale:上下⽂区域设置。
  4. #request :(仅在Web Contexts中)HttpServletRequest对象。
  5. #response:(仅在Web上下⽂中)HttpServletResponse对象。
  6. #session :(仅在Web上下⽂中)HttpSession对象。
  7. #servletContext :(仅在Web上下⽂中)ServletContext对象。

1.2.3 常用的内置方法

  1. 一、strings:字符串格式化方法,常用的Java方法它都有。
  2. 比如:equalsequalsIgnoreCaselengthtrimtoUpperCasetoLowerCaseindexOfsubstringreplacestartsWithendsWithcontainscontainsIgnoreCase
  3. 二、numbers:数值格式化方法。
  4. 常用的方法有:formatDecimal
  5. 三、bools:布尔方法。
  6. 常用的方法有:isTrueisFalse
  7. 四、arrays:数组方法。
  8. 常用的方法有:toArraylengthisEmptycontainscontainsAll
  9. 五、listssets:集合方法。
  10. 常用的方法有:toListsizeisEmptycontainscontainsAllsort
  11. 六、maps:对象方法。
  12. 常用的方法有:sizeisEmptycontainsKeycontainsValue
  13. 七、dates:日期方法。
  14. 常用的方法有:formatyearmonthhourcreateNow

1.2.4 示例

  1. @RequestMapping("varexpressions")
  2. public String varexpressions(ModelMap map) {
  3. map.put("itdragonStr", "itdragonBlog");
  4. map.put("itdragonBool", true);
  5. map.put("itdragonArray", new Integer[]{1,2,3,4});
  6. map.put("itdragonList", Arrays.asList(1,3,2,4,0));
  7. Map itdragonMap = new HashMap();
  8. itdragonMap.put("thName", "${#...}");
  9. itdragonMap.put("desc", "变量表达式内置方法");
  10. map.put("itdragonMap", itdragonMap);
  11. map.put("itdragonDate", new Date());
  12. map.put("itdragonNum", 888.888D);
  13. return "grammar/varexpressions";
  14. }
  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>ITDragon Thymeleaf 内置方法</title>
  6. </head>
  7. <body>
  8. <h2>ITDragon Thymeleaf 内置方法</h2>
  9. <h3>#strings </h3>
  10. <div th:if="${not #strings.isEmpty(itdragonStr)}" >
  11. <p>Old Str : <span th:text="${itdragonStr}"/></p>
  12. <p>toUpperCase : <span th:text="${#strings.toUpperCase(itdragonStr)}"/></p>
  13. <p>toLowerCase : <span th:text="${#strings.toLowerCase(itdragonStr)}"/></p>
  14. <p>equals : <span th:text="${#strings.equals(itdragonStr, 'itdragonblog')}"/></p>
  15. <p>equalsIgnoreCase : <span th:text="${#strings.equalsIgnoreCase(itdragonStr, 'itdragonblog')}"/></p>
  16. <p>indexOf : <span th:text="${#strings.indexOf(itdragonStr, 'r')}"/></p>
  17. <p>substring : <span th:text="${#strings.substring(itdragonStr, 2, 8)}"/></p>
  18. <p>replace : <span th:text="${#strings.replace(itdragonStr, 'it', 'IT')}"/></p>
  19. <p>startsWith : <span th:text="${#strings.startsWith(itdragonStr, 'it')}"/></p>
  20. <p>contains : <span th:text="${#strings.contains(itdragonStr, 'IT')}"/></p>
  21. </div>
  22. <h3>#numbers </h3>
  23. <div>
  24. <p>formatDecimal 整数部分随意,小数点后保留两位,四舍五入: <span th:text="${#numbers.formatDecimal(itdragonNum, 0, 2)}"/></p>
  25. <p>formatDecimal 整数部分保留五位数,小数点后保留两位,四舍五入: <span th:text="${#numbers.formatDecimal(itdragonNum, 5, 2)}"/></p>
  26. </div>
  27. <h3>#bools </h3>
  28. <div th:if="${#bools.isTrue(itdragonBool)}">
  29. <p th:text="${itdragonBool}"></p>
  30. </div>
  31. <h3>#arrays </h3>
  32. <div th:if="${not #arrays.isEmpty(itdragonArray)}">
  33. <p>length : <span th:text="${#arrays.length(itdragonArray)}"/></p>
  34. <p>contains : <span th:text="${#arrays.contains(itdragonArray, 5)}"/></p>
  35. <p>containsAll : <span th:text="${#arrays.containsAll(itdragonArray, itdragonArray)}"/></p>
  36. </div>
  37. <h3>#lists </h3>
  38. <div th:if="${not #lists.isEmpty(itdragonList)}">
  39. <p>size : <span th:text="${#lists.size(itdragonList)}"/></p>
  40. <p>contains : <span th:text="${#lists.contains(itdragonList, 0)}"/></p>
  41. <p>sort : <span th:text="${#lists.sort(itdragonList)}"/></p>
  42. </div>
  43. <h3>#maps </h3>
  44. <div th:if="${not #maps.isEmpty(itdragonMap)}">
  45. <p>size : <span th:text="${#maps.size(itdragonMap)}"/></p>
  46. <p>containsKey : <span th:text="${#maps.containsKey(itdragonMap, 'thName')}"/></p>
  47. <p>containsValue : <span th:text="${#maps.containsValue(itdragonMap, '#maps')}"/></p>
  48. </div>
  49. <h3>#dates </h3>
  50. <div>
  51. <p>format : <span th:text="${#dates.format(itdragonDate)}"/></p>
  52. <p>custom format : <span th:text="${#dates.format(itdragonDate, 'yyyy-MM-dd HH:mm:ss')}"/></p>
  53. <p>day : <span th:text="${#dates.day(itdragonDate)}"/></p>
  54. <p>month : <span th:text="${#dates.month(itdragonDate)}"/></p>
  55. <p>monthName : <span th:text="${#dates.monthName(itdragonDate)}"/></p>
  56. <p>year : <span th:text="${#dates.year(itdragonDate)}"/></p>
  57. <p>dayOfWeekName : <span th:text="${#dates.dayOfWeekName(itdragonDate)}"/></p>
  58. <p>hour : <span th:text="${#dates.hour(itdragonDate)}"/></p>
  59. <p>minute : <span th:text="${#dates.minute(itdragonDate)}"/></p>
  60. <p>second : <span th:text="${#dates.second(itdragonDate)}"/></p>
  61. <p>createNow : <span th:text="${#dates.createNow()}"/></p>
  62. </div>
  63. </body>
  64. </html>

1.3 选择表达式 *{---}

  1. <div th:object="${session.user}">
  2. <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
  3. <p>Surname: <span th:text="*{lastName}">Pepper</span>. </p>
  4. <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
  5. </div>

这完全等同于:

  1. <div>
  2. <p>Name: <span th:text="${session.user.firstName}">Sebastian</span>.</p>
  3. <p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p>
  4. <p>Nationality: <span th:text="${session.user.nationality}">Saturn</span>.</p>
  5. </div>

当然,${---}*{---}的语法可以混合使⽤:

  1. <div th:object="${session.user}">
  2. <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
  3. <p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p>
  4. <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
  5. </div>

使用th:object 指定的执行对象,也可⽤于${---}表达式:

  1. <div th:object="${session.user}">
  2. <p>Name: <span th:text="${#object.firstName}">Sebastian</span>.</p>
  3. <p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p>
  4. <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
  5. </div>

如果没有执⾏对象选择,则${---}*{---}是等效的:

  1. <div>
  2. <p>Name: <span th:text="*{session.user.name}">Sebastian</span>.</p>
  3. <p>Surname: <span th:text="*{session.user.surname}">Pepper</span>.</p>
  4. <p>Nationality: <span th:text="*{session.user.nationality}">Saturn</span>.</p>
  5. </div>

1.4 链接表达式 @{---}

首先来认识th:href属性:

  1. <!-- Will produce 'http://localhost:8080/gtvg/order/details?orderId=3' (plus rewriting) -->
  2. <a href="details.html" th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">view</a>
  3. <!-- Will produce '/gtvg/order/details?orderId=3' (plus rewriting) -->
  4. <a href="details.html"
  5. th:href="@{/order/details(orderId=${o.id})}">view</a>
  6. <!-- Will produce '/gtvg/order/3/details' (plus rewriting) -->
  7. <a href="details.html"
  8. th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>

注意:

  • th:href是⼀个修饰符属性:⼀旦处理,它将计算要使⽤的链接URL,并将该值设置为标签的href属性。
  • 我们被允许使⽤表达式的URL参数(可以在orderId = $ {o.id}中看到)。所需的URL参数编码操作也将⾃动执⾏。
  • 如果需要⼏个参数,这些参数将以逗号分隔:@ {/ order /process(execId = $ {execId},execType ='FAST')}
  • URL路径中也允许使⽤变量模板:@ {/ order / {orderId} /details(orderId = $ {orderId})}
  • 以/开头的相对URL(例如:/ order / details)将⾃动以应⽤程序上下⽂名称为前缀。
  • 如果cookie未启⽤或尚未知道,则可能会在相对URL中添加“;jsessionid = ...”后缀,以便会话被保留。这被称为URL重写,Thymeleaf允许您使⽤Servlet API中的每个URL的response.encodeURL(...)机制来插⼊⾃⼰的重写过滤器。
  • th:href属性允许我们(可选地)在我们的模板中有⼀个⼯作的静态href属性,这样当我们直接打开原型设计时,我们的模板链接可以被浏览器导航。

与消息语法(#{—-})的情况⼀样,URL基数也可以是计算另⼀个表达式的结果:

  1. <a th:href="@{${url}(orderId=${o.id})}">view</a>
  2. <a th:href="@{'/details/'+${user.login}(orderId=${o.id})}"
  3. >view</a>

1.4.1 主⻚菜单

我们知道如何创建链接⽹址,如何在⽹站的其他⼀些⻚⾯中添加⼀个⼩菜单呢?

  1. <p>Please select an option</p>
  2. <ol>
  3. <li><a href="product/list.html" th:href="@{/product/list}">Product List</a></li>
  4. <li><a href="order/list.html" th:href="@{/order/list}">Order List</a></li>
  5. <li>
  6. <a href="subscribe.html" th:href="@{/subscribe}">Subscribe to our Newsletter</a> </li>
  7. <li><a href="userprofile.html" th:href="@{/userprofile}">See User Profile</a></li>
  8. </ol>

1.4.2 服务器相对URL

可以使⽤附加语法来创建服务器根⽬录(⽽不是上下⽂相对)URL,以链接到同⼀服务器中的不同上下⽂。 这些URL将被指定为@ {〜/path/to/something}

1.5 表达式支持的语法

字面(Literals)

  • 文本文字(Text literals): 'one text', 'Another one!',…
  • 数字文本(Number literals): 0, 34, 3.0, 12.3,…
  • 布尔文本(Boolean literals): true, false
  • 空(Null literal): null
  • 文字标记(Literal tokens): one, sometext, main,…

文本操作(Text operations)

  • 字符串连接(String concatenation): +
  • 文本替换(Literal substitutions): |The name is ${name}|

算术运算(Arithmetic operations)

  • 二元运算符(Binary operators): +, -, *, /, %
  • 减号(单目运算符)Minus sign (unary operator): -

布尔操作(Boolean operations)

  • 二元运算符(Binary operators):and, or
  • 布尔否定(一元运算符)Boolean negation (unary operator):!, not

比较和等价(Comparisons and equality)

  • 比较(Comparators): >, <, >=, <= (gt, lt, ge, le)
  • 等值运算符(Equality operators):==, != (eq, ne)

条件运算符(Conditional operators)

  • If-then: (if) ? (then)
  • If-then-else: (if) ? (then) : (else)
  • Default: (value) ?: (defaultvalue)

1.6 代码块表达式

2. 常用Th属性

html有的属性,Thymeleaf基本都有,而常用的属性大概有七八个。其中th属性执行的优先级从1~8,数字越低优先级越高。

2.1 th:id 替换id属性

示例:

  1. <input th:id="'xxx' + ${collect.id}"/> //collect.id = 001

等价于:

  1. <input id="xxx001"/>

2.2 th:text body文本替换

示例:

  1. <p th:text="${collect.description}">description</p> //collect.description = very good!

等价于:

  1. <p>very good!</p>

2.3 th:utext body文本替换(非格式转换)

示例:

  1. <div th:utext = "${collection.htmlStr}"></div>
  2. //collection.htmlStr = "<h2>这是标题2</h2>"

等价于:

  1. <div><h2>这是标题2</h2></div>

2.4 th:object 替换对象

2.5 th:attr设置标签属性

2.6 th:value设置当前元素的value值

2.7 th:href设置当前元素的 链接地址

2.8 th:src图片类地址引入

2.9 th:if条件判断

示例:

  1. <div th:if="${num} gt 2" >情景一</div> //num = 3
  2. <div th:if="${num} lt 2" >情景二</div>
  1. 比较运算符:
  2. gtgreat than(大于)>
  3. gegreat equal(大于等于)>=
  4. eqequal(等于)==
  5. ltless than(小于)<
  6. leless equal(小于等于)<=
  7. nenot equal(不等于)!=

等价于:

  1. <div>情景一</div>

2.10 th:unless条件判断,与th:if相反

2.11 th:switch条件判断,与th:case配合使用

  1. <div th:switch="${collection.enable}">
  2. <p th:case="0">情景1</p>
  3. <p th:case="1">情景2</p>
  4. <p th:case="2">情景3</p>
  5. </div>

collection.enable = 2,则可就等价于:

  1. <div><p>情景3</p></div>

2.12 th:each遍历循环元素

示例:

  1. <table>
  2. <tr th:each="user:${userlist}">
  3. <td th:text="${user.id}"></td>
  4. <td th:text="${user.username}"></td>
  5. <td th:text="${user.password}"></td>
  6. <td th:text="${user.petname}"></td>
  7. </tr>
  8. </table>

如果userList为:

  1. 1,libai,001,小1
  2. 2,lanlw,002,小2
  3. 2,sulie,003,小3

等价于:

  1. <table>
  2. <tr>
  3. <td >1</td>
  4. <td >libai</td>
  5. <td >001</td>
  6. <td>小1</td>
  7. </tr>
  8. <tr>
  9. <td >2</td>
  10. <td >lanlw</td>
  11. <td >001</td>
  12. <td>小2</td>
  13. </tr>
  14. <tr>
  15. <td >3</td>
  16. <td >sulie</td>
  17. <td >001</td>
  18. <td>小3</td>
  19. </tr>
  20. </table>

2.13 th:style设置样式

2.14 th:fragment定义一个代码片段,方便其它地方引用

2.15 th:insert,th:replaceth:include代码块引入

  1. 关于thymeleaf th:replace th:include th:insert 的区别
  2. th:insert :保留自己的主标签,保留th:fragment的主标签。
  3. th:replace :不要自己的主标签,保留th:fragment的主标签。
  4. th:include :保留自己的主标签,不要th:fragment的主标签。(官方3.0后不推荐)

示例:

  1. //需要替换的片段内容:
  2. <footer th:fragment="copy">
  3. <script type="text/javascript" th:src="@{/plugins/jquery/jquery-3.0.2.js}"></script>
  4. </footer>
  1. //导入片段:
  2. <div th:insert="footer :: copy"></div>
  3. <div th:replace="footer :: copy"></div>
  4. <div th:include="footer :: copy"></div>
  1. //结果为:
  2. <div>
  3. <footer>
  4. <script type="text/javascript" th:src="@{/plugins/jquery/jquery-3.0.2.js}"></script>
  5. </footer>
  6. </div>
  7. <footer>
  8. <script type="text/javascript" th:src="@{/plugins/jquery/jquery-3.0.2.js}"></script>
  9. </footer>
  10. <div>
  11. <script type="text/javascript" th:src="@{/plugins/jquery/jquery-3.0.2.js}"></script>
  12. </div>

2.15 th:remove删除模板片段

th:remove的值如下:

  1.   1.all:删除包含标签和所有的孩子。
  2.   2.body:不包含标记删除,但删除其所有的孩子。
  3.   3.tag:包含标记的删除,但不删除它的孩子。
  4.   4.all-but-first:删除所有包含标签的孩子,除了第一个。
  5.   5.none:什么也不做。这个值是有用的动态评估。

示例:

  1. <table>
  2. <tr th:each="number : ${#numbers.sequence(0, 5)}">
  3. <td th:remove="none">
  4. <span th:text="|user-| + ${number}"></span>***
  5. <span th:text="${number}"></span>
  6. </td>
  7. </tr>
  8. </table>
  • 如果th:remove取值为all,则会删除td以及其子元素
  • 取值为body时,将td下的全部子元素删除
  • 取值为tag,会删除td,不会删除两个span。
  • 取值为all-but-first,删除自己下面全部子元素,不删除第一个
  • 取值为none,不进行任何操作。

3. ThymeleafSpringBoot中的使用

  1. spring.thymeleaf.cache = true 启用模板缓存(开发时建议关闭)
  2. spring.thymeleaf.check-template = true 检查模板是否存在,然后再呈现
  3. spring.thymeleaf.check-template-location = true 检查模板位置是否存在
  4. spring.thymeleaf.content-type = text/html Content-Type
  5. spring.thymeleaf.enabled = true 启用MVC Thymeleaf视图分辨率
  6. spring.thymeleaf.encoding = UTF-8 模板编码
  7. spring.thymeleaf.excluded-view-names = 应该从解决方案中排除的视图名称的逗号分隔列表
  8. spring.thymeleaf.mode = HTML5 应用于模板的模板模式。另请参见StandardTemplateModeHandlers
  9. spring.thymeleaf.prefix = classpath:/templates/ 在构建URL时预先查看名称的前缀
  10. spring.thymeleaf.suffix = .html 构建URL时附加查看名称的后缀
  11. spring.thymeleaf.template-resolver-order = 链中模板解析器的顺序
  12. spring.thymeleaf.view-names = 可以解析的视图名称的逗号分隔列表