Thymeleaf模板引擎常规使用技巧整理

阅读原文
Thymelaf是适用于web和独立环境的服务器端的Java模板引擎,它的主要目标使得模板开发的工作流程优雅自然,它定义的模板HTML可以在浏览器中正确渲染,也可以作为静态原型文件工作,这是它的最大亮点,它提供有适用于spring框架的模块,便于开发人员整合。

一、整合Thymeleaf

1、引入依赖

<!-- thymeleaf依赖 -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2、自定义配置

默认情况下不用做任何配置即可满足常规需求,但是为了开发方便需要关闭Thymeleaf缓存,配置如下:

spring.thymeleaf.cache=false

此配置主要是方便我们在模板中修改的内容能够实时的渲染。

3、模板位置

模板位置默认在springboot项目resources/templates下,一般情况下不建议修改此目录。

4、创建测试控制器

@Controller
public class TestController {
  @Autowired
  MessageSource messageSource;
​
  @RequestMapping("/")
  public String index(Model model) {
    return "forward:index";
  }

 @RequestMapping("/index")
  public String toIndex(Model model, HttpSession session) {
    List<Person> personList = new ArrayList<>();
    Person person = new Person("1","张三", "大小伙");
    Person person1 = new Person("2","李四", "大姑娘");
    Person person2 = new Person("3","王五", "小孩儿");
    personList.add(person);
    personList.add(person1);
    personList.add(person2);
    model.addAttribute("person", person);
    model.addAttribute("testVariables", "测试");
    model.addAttribute("cssStyle", "cssStyle");
    model.addAttribute("testClass", "testClass");
    model.addAttribute("personList", personList);
    model.addAttribute("currentTime", new Date());
    session.setAttribute("sessionAttr", "sessionAttr");
    ServletContext servletContext = session.getServletContext();
    servletContext.setAttribute("applicationAttr", "applicationAttr");
    return "index";
  }
}

二、参数获取

获取普通属性表达式:${x}
获取请求参数表达式:${param.x}
获取session属性表达式:${session.x}
获取application属性表达式:${application.x}

三、表达式使用

链接表达式:@{}
属性选择表达式:*{}
messge表达式:#{}
片段引用表达式:~{}
内嵌表达式:[[]]
栗子,表达式使用

<h3>变量表达式--${...}</h3>
<p><span th:text="${testVariables}"></span></p>
​
<h3>选择变量表达式--*{...}</h3>
<p>
    <div th:object="${person}">
        <p>姓名:<span th:text="*{name}"></span></p>
        <p>年龄:<span th:text="*{desc}"></span></p>
    </div>
</p>
​
<h3>链接表达式--@{...}、th:href</h3>
<p>
    <!-- 最终转化结果:'http://localhost:8080/gtvg/order/details?orderId=3'  -->
    <a href="details.html"
       th:href="@{http://localhost:8080/gtvg/order/details(orderId=${person.id})}">view</a>
    <!-- 最终转化结果:'/gtvg/order/details?orderId=3'  -->
    <a href="details.html" th:href="@{/order/details(orderId=${person.id})}">view</a>
    <!-- 最终转化结果:'/gtvg/order/details/3'  -->
    <a href="details.html" th:href="@{/order/details/{orderId}(orderId=${person.id})}">view</a>
</p>

message表达式主要用于读取国际化属性配置文件中的属性,springboot默认的属性配置文件名称为:messages,位置为:resource文件夹下。
定义messages.properties文件

welcome= welcome thymeleaf index

栗子,读取messages属性

<p th:text="#{welcome}"></p>

内嵌表达式主要是在js或者css中获取属性变量时使用,例如:

<script>
      var arg1 = '[[${testVariables}]]';
      console.log(arg1);
</script>

这里需要注意一点,如果你的页面是thymeleaf模板,则在js中使用二维数组时,要将括号换行,否则thymeleaf在解析时会将其当做内嵌表达解析,从而导致报错,这也是thymeleaf比较诟病的一特征。

var array = [
                [...],
                [...]
            ];

四、标签使用

thymeleaf的标签库非常丰富,它是一个独立的标签库,没有对html原型页面做任何的侵入操作,由于html对thymeleaf标签无法感知,所以使用此标签库需要定义标签库的描述信息,如下:

<html xmlns:th="http://www.thymeleaf.org" lang="en">

有了此描述信息的定义,html页面就可以感知thymeleaf的标签库了。

1、常用标签

th:href:定义html域href属性
th:id:定义html域id属性
th:name:定义html域name属性
th:value:定义html域value属性
th:class:定义html域class属性
th:attr:自定义属性
以上都是一些常用的标签,当然还有很多属性标签,需要用时可查找thymeleaf官方文档即可
栗子,使用常用标签

<!--最终渲染结果:<input id="user" name="user" placeholder="请输入用户名" value="" data-filter="test">-->
<input th:id="user" th:name="user" th:placeholder="请输入用户名" th:value="''" th:attr="data-filter='test'"

2、文本标签

th:text:输出普通文本
th:utext:输出html文本
栗子,使用文本标签

<p th:text="'<h3>hello world!</h3>'"></p>
<p th:utext="'<h3>hello world!</h3>'"></p>

渲染效果


image

3、追加前置标签

th:attrappend:正常追加
th:attrprepending:前置追加
栗子,使用追加前置标签

<!-- 最终渲染追加效果 <input type="button" value="Do it!" class="btn warning" /> -->
<input type="button" value="append" class="btn" th:attrappend="class=${' ' + cssStyle}" />
<!-- 最终渲染前置效果 <input type="button" value="Do it!" class="warning btn" /> -->
<input type="button" value="prepending" class="btn" th:attrprepend="class=${cssStyle + ' '}" />

4、条件判断标签

th:if:if判断
th:switch:switch判断
th:case:case匹配

1、使用条件判断标签时,不可避免要使用到运算符,在thymeleaf模板中使用运算符文本别名可以避免html渲染时的转义问题,,文本别名如下:

gt (>), lt (<), ge (>=), le (<=), not (!). eq (==), neq/ne (!=)

2、th:if条件判断规则如下:

1、布尔值为true则为true
2、非0数字则为true
3、任意字符则为true
4、非“false”, “off” or “no”字符串则为true
5、如果为null则为false

栗子,th:if标签使用

<table width="40%" cellpadding="0" cellspacing="0" border="1">
    <tr>
        <td>姓名</td>
        <td>描述</td>
        <td>操作</td>
    </tr>
    <tr th:each="per : ${personList}">
        <td th:text="${per.name}"></td>
        <td th:text="${per.desc}"></td>
        <td><a href="#" th:if="${per.id == '2' && per.name == '李四'}">view</a></td>
    </tr>
</table>

渲染效果

image

栗子,th:switch、th:case标签使用

 <ul style="list-style-type: decimal" th:switch="${testVariables}">
      <li th:case="'测试'">测试</li>
      <!--*类似于default-->
      <li th:case="*">默认(都匹配不成功)</li>
  </ul>

5、迭代标签

th:each:迭代标签,需要注意的是迭代标签有一个状态变量,默认情况下该变量名称为定义的迭代变量名称后追加Stat,此变量有如下属性可供使用:

1、index:索引,
2、count:数量,
3、current:当前变量,
4、first:是否为第一个列表元素,
5、last:是否为最后一个元素,
6、even:count是否为偶数,
7、odd:count是否为奇数,
8、size:列表元素总数

栗子

<table width="40%" cellpadding="0" cellspacing="0" border="1">
    <tr>
        <td>姓名</td>
        <td>描述</td>
        <td width="70%">其他</td>
    </tr>
    <tr th:each="per : ${personList}">
        <td th:text="${per.name}"></td>
        <td th:text="${per.desc}"></td>
        <td th:text="
        '索引:' + ${perStat.index} +
        ',数量:' +  ${perStat.count} +
        ',当前变量:' + ${perStat.current} +
        ',是否为第一个列表元素:' +  ${perStat.first} +
        ',是否为最后一个元素:' + ${perStat.last} +
        ',count是否为偶数' + ${perStat.even} +
        ',count是否为奇数' + ${perStat.odd} +
        ',列表元素总数:' + ${perStat.size}
"></td>
    </tr>
</table>

渲染效果

image

以上只是对迭代状态属性做一演示,无实质意义。

6、自定义标签

关于自定义标签的使用,主要是在开发过程中封装一些公共组件,例如:select、radio等,在使用时直接编写此标签即可,由于本篇文章内容过多,关于自定义标签的使用,我会在下一篇文章中来说明。

五、布局

我们在页面布局时,为了处理公共头部和尾部需要做代码片段的引入,thymeleaf很好的支持了这一功能,只需使用片段表达式和标签即可。
1、片段定义标签:th:fragment
2、片段引用标签:th:insert、th:replace、th: include
3、片段引用标签说明:
th:insert:将片段内容元素直接插入目标元素
th:replace:将目标元素替换为片段内容元素
th:include:只将片段内容包含至目标元素
栗子、定义公共模板

<footer th:fragment="footer(arg1, arg2)">
    公共页脚-传入参数:<span th:text="${arg1}"></span> -- <span th:text="${arg2}"></span>
</footer>

栗子、使用模板

 <!-- 渲染结果:<div><footer>公共页脚</footer></div>-->
  <div th:insert="~{/common/fragment :: footer('test', '测试')}"> </div>
  <!-- 渲染结果: <footer>公共页脚</footer>-->
  <div th:replace="~{/common/fragment :: footer('test', '测试')}">  </div>
  <!-- 渲染结果: <div>公共页脚</div>-->
  <div th:include="~{/common/fragment :: footer('test', '测试')}">  </div>

tips:
/common/fragment:模板路径;
footer('test', '测试'):footer,模板引用,括号中为传入的参数。

六、工具对象使用

所有的thymeleaf内置对象均可通过${#内置对象}的方式获取,下面将常用的工具对象做一演示,更多工具对象的使用可以参考官方文档。

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#appendix-b-expression-utility-objects

栗子,常用工具对象的使用

<ul style="list-style-type: decimal">
    <li>日期格式化:<span th:text="${#dates.format(currentTime, 'yyyy-MM-dd HH:mm:ss.SSS')}"></span></li>
    <li>金额格式化:<span th:text="${#numbers.formatCurrency(200001.12)}"></span></li>
    <li>list判断为空:<span th:if="${not #lists.isEmpty(personList)}" th:text="'不为空'"></span></li>
</ul>

渲染效果

image

至此,关于Thymeleaf的使用以及与SpringBoot的整合就介绍完了,有任何的问题和建议可以在博客或公众号后台留言,我会及时处理。

更多最新技术文章,请关注“冰点IT”公众号

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容