Thymeleaf的语法详情及使用

作者: 右耳菌 | 来源:发表于2022-05-05 21:06 被阅读0次

    官网: https://www.thymeleaf.org/documentation.html

    1. 什么是 Thymeleaf

    • Thymeleaf是⾯向Web和独⽴环境的现代服务器端Java模板引擎,能够处 理HTML,XML,JavaScript,CSS甚⾄纯⽂本。
    • Thymeleaf旨在提供⼀个优雅的、⾼度可维护的创建模板的⽅式。 为了实 现这⼀⽬标,Thymeleaf建⽴在⾃然模板的概念上,将其逻辑注⼊到模板 ⽂件中,不会影响模板设计原型。 这改善了设计的沟通,弥合了设计和 开发团队之间的差距。
    • Thymeleaf从设计之初就遵循Web标准——特别是HTML5标准 ,如果需 要,Thymeleaf允许您创建完全符合HTML5验证标准的模板。
    • Tips:
      Spring Boot 体系内推荐使用Thymeleaf作为前端页面模板,并且Spring Boot 2.0 中默认使用 Thymeleaf 3.0,性能提升幅度很大。

    2. Thymeleaf的特点

    1. Thymeleaf在不管是否连接服务器的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。
    2. Thymeleaf开箱即用的特性。它支持标准方言和Spring 方言,可以直接套用模板实现JSTL、OGNL表达式效果,避免每天套模板、改JSTL、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。
    3. Thymeleaf提供Spring标准方言和一个与SpringMVC完美集成的可选模块,可以快速地实现表单绑定、属性编辑器、国际化等功能
    4. Thymeleaf相关知识脑图


      Thymeleaf相关知识脑图

    3. Thymeleaf的快速入门 (简单例子)

      1. 新建一个Springboot项目,加上Thymeleaf的starter
        pom.xml (仅展示重要依赖)
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
      1. 配置properties文件,加上不开启Thymeleaf的缓存
    spring.thymeleaf.cache=false
    
      1. 创建hello.html
    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <p>欢迎使用Thymeleaf模板</p>
        <p th:text="${msg}">这是静态段落文字</p>
    </body>
    </html>
    
      1. 创建HelloController
    package cn.lazyfennec.springbootthymeleaf.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     * @Author: Neco
     * @Description:
     * @Date: create in 2022/5/4 16:20
     */
    @Controller
    public class HelloController {
    
        @RequestMapping("/hello")
        public String hello(ModelMap map) {
            map.addAttribute("msg", "Hello Neco!!!");
            return "hello";
        }
    
    }
    

    4. Thymeleaf 的基本语法 - th属性

      1. 文本属性
    • 文本拼接:||
    • 文本信息:th:text,th:id,th:value...
    • 文本信息(可以解析HTML各位): th:utext
        @RequestMapping("/hello")
        public String hello(ModelMap map){
            map.addAttribute("message","你好<b>这里加粗了</b>");
            map.put("id","这是id");
            map.put("value","这是value");
            map.put("utext","这是utext里面的内容<b>这里加粗了</b>");
            return "hello";
        }
    
    <body>
        <!--文本属性-字符串的拼接:写法1-->
        <p th:text="|welcome to shanghai,${message}|"></p>
        <!--文本属性-字符串的拼接:写法2-->
        <p th:utext="'welcome to shanghai,'+${message}"></p>
        <!--文本属性-id属性-->
        <p th:id="${id}"></p>
        <!--文本属性-value属性-->
        <input th:value="${value}"/>
        <!--使用内联标签来书写-->
        <!--不带html的解析,类似于th:text-->
        <p>[[|welcome to shanghai,${message}|]]</p>
        <!--带html的解析,类似于th:utext-->
        <p>[('welcome to shanghai,'+${message})]</p>
        <!--也可以直接写文本-->
        <p>[['welcome to shanghai']]</p>
    </body>
    
      1. 条件属性
    • if判断:th:if
    • unless判断:th:unless
    • switch判断:th:switch...th:case
        @RequestMapping("/if")
        public String hello(ModelMap map){
            map.put("flag","yes");
            map.put("baidu","http://www.baidu.com");
            map.put("taobao","http://www.taobao.com");
            map.put("age",19);
            return "if";
        }
    
    <body>
        <!--if:如果条件成立,就展示-->
        <!--th:href:允许在href属性里面使用thymeleaf语法,超链接需要用@{}开头,里面可以写model里面的key-->
        <a th:if="${flag eq 'yes'}" th:href="@{${baidu}}">baidu1</a><br>
        <!--th:href:专门用来使用URL地址的,既可以直接像上面那样在里面直接写${},
        也可以先定义个变量用大括号括起来然后在url的最后面使用一个小括号来对该变量进行赋值-->
        <a th:if="${flag eq 'yes'}"
           th:href="@{{baidusite}(baidusite=${baidu})}">baidu2</a><br>
        <!--直接在href里面写${}是无法获取到后台model里面的数据的-->
        <a th:if="${flag eq 'yes'}" href="${baidu}">baidu3</a><br>
        <!--不使用th:href的话,href里面只能写死的数据-->
        <a th:if="${flag eq 'no'}" href="http://www.baidu.com">baidu4</a><br>
        <!--unless:如果条件不成立,就展示-->
        <a th:unless="${flag eq 'no'}" th:href="@{http://www.taobao.com}">taobao</a>
        <!--使用switch-->
        <div th:switch="${age}">
            <p th:case="18">这是张三</p>
            <p th:case="19">这是李四</p>
            <p th:case="20">这是王五</p>
            <p th:case="*">这是谁我不认识</p>
        </div>
    </body>
    
      1. 循环属性-th:each
    • th:each迭代list
    • th:each的内置属性
    • th:each迭代map
        @RequestMapping("/list")
        public String list(ModelMap map){
            List<User> list = getUserList();
            map.addAttribute("list",list);
            return "list";
        }
    
      <table>
           <tr>
               <th>姓名</th>
               <th>年龄</th>
               <th>密码</th>
           </tr>
           <tr th:each="user:${list}">
               <td th:text="${user.name}"></td>
               <td th:text="${user.age}"></td>
               <td th:text="${user.pass}"></td>
           </tr>
       </table>
    

    5. Thymeleaf的表达式语法

    • ${...}变量表达式:也叫OGNL表达式或Spring EL表达式,用于调用各种属性和方法
    • a) 可以获取对象的属性和方法
    • b) 可以使用ctx, vars, locale, request, response, session, servletContext内置对象
    • c) 可以使用dates, numbers, strings, objects, arrays, lists, sets, maps等内置方法
    • @{...}链接表达式:不管是静态资源的引用,form表单的请求,凡是链接都可以用@{...]
    • a) 无参:@{/xxx}
    • b) 有参:@{/xxx(k1=v1,k2=v2)},对应url结构:xxx?k1=v1&k2=v2
    • c) 引入本地资源:@{/项目本地的资源路径}
    • d) 引入外部资源:@{/webjars/资源在jar包中的路径}
    • #{...} 消息表达式:用于从消息源中提取消息内容实现国际化
    • 语法和变量表达式相比多了个获取参数的方式
    • 消息源主要是properties文件
    • ~{...}代码块表达式:把某一段定义好的代码块插入到另一个页面中,一般用于定义出一套通用的header或者是footer
    • 语法:~[templatename:fragmentname}或者~[templatename:.id},如果省略templatename,它将在当前页面进行寻找指定的代码块,注意:~可以省略
      a) templatename:模版名,定义模板的写法:<footer th:fragment="copy">
      b) fragmentname:片段名,引入模板的写法: <div th:insert="comm/foot : copy">
      c) id: HTML的id选择器,使用时要在前面加上#号,不支持class选择器
    • 代码块表达式需要配合th属性(th:insert,th:replace,th:include)一起使用。
      a) th:insert:将代码块片段整个插入到使用了th:insert的HTML标签中
      b) th:replace:将代码块片段整个替换使用了th:replace的HTML标签中
      c) th:include:将代码块片段包含的内容插入到使用了th:include的HTML标签中
    • *{...}选择变量表达式:是另一种类似${...},在某些时候,两者是等价的,选择变量表达式在执行时是在选择的对象上求解(使用th:object来选择对象),而${...}是在上下文的变量Map上求解。
    • 两者获取对象里边属性的方法
    • 两者进行混用的条件

    6. Thymeleaf中表达式支持的语法

    • 字面
    • 文本文字: 'one text','Another one!',...
    • 数字文字:0,34,3.0,12.3,...
    • 布尔文字: true,false
    • 空字面: null
    • 文字操作:
    • 字符串连接:+
    • 文字替代:|The name is ${name}
    • 算术运算:
    • 运算符: +,-,*,/,%
    • 布尔运算:
    • 二元运算符:and,or
    • 布尔否定(一元运算符)∶ !, not
    • 比较和相等
    • 比较:>, <,>=,<= (gt,lt,ge,le)
    • 相等判断:==,!= (eq,ne)
    • 条件运算符
    • lF-THEN:(if) ? (then)
    • lF-THEN-ELSE: (if) ? (then) : (else)
    • 默认: (value) ?: (defaultvalue)

    7. Thymeleaf中的基础对象

    • #ctx:上下文对象
    • #vars:上下文对象(和#ctx相同,但是一般用#ctx)
    • #locale:区域对象
    • #request:(仅Web环境可用)HttpServletRequest对象
    • #response:(仅 Web环境可用)HttpServletResponse对象
    • #session:(仅Web环境可用)HttpSession对象
    • #servletContext:(仅Web环境可用)ServletContext 对象
    • param:获取请求的参数
    • session:访问session属性
    • application:获取应用程序/ servlet上下文属性

    注意:以上三个不带#的对象,都拥有以下方法:size(),isEmpty(),containsKey(), .key

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>if,unless</title>
    </head>
    <body>
        <h1>ctx上下文对象</h1>
        <p th:text="${#ctx}"></p>
        <h1>ctx获取保存在map里的数据</h1>
        <p th:text="${#ctx.getVariable('a')}"></p>
        <h1>vars上下文变量</h1>
        <p th:text="${#ctx}"></p>
        <h1>locale区域对象</h1>
        <p th:text="${#locale}"></p>
        <p th:text="${#locale.country}"></p>
        <h1>param的使用</h1>
    <!--    http://127.0.0.1:8088/baseObject?a=1&b=2&c=3,
        param代表获取到请求里的参数-->
        <p th:text="|size:${param.size()},a:${param.a}|"></p>
        <h1>来获取session里面的对象</h1>
        <p th:text="${#session.getAttribute('session')}"></p>
        <p th:text="${session.session}"></p>
    </body>
    </html>
    
    package com.study.thymeleaf.thymeleafdemo.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    
    /**
     * @Author 来苏
     * 测试基础对象
     * #ctx、#vars、#locale
     */
    @Controller
    public class BaseObjectController {
        @RequestMapping("/baseObject")
        public String map1(ModelMap map, HttpServletRequest request, HttpSession session) {
            map.put("a", 123);
            map.put("b", "bbb");
            request.setAttribute("request", "123");
            session.setAttribute("session", "321");
            return "base";
        }
    }
    

    8. Thymeleaf的常用工具类

    • #strings:字符串工具类
    • #lists: List工具类
    • #arrays:数组工具类
    • #sets: Set工具类
    • #maps:常用Map方法。
    • #objects:一般对象类,通常用来判断非空
    • #bools:常用的布尔方法。
    • #execInfo:获取页面模板的处理信息。
    • #messages:在变量表达式中获取外部消息的方法,与使用#{...}语法获取的方法相同。
    • #uris:转义部分URL/URI的方法。
    • #conversions:用于执行已配置的转换服务的方法。
    • #dates:时间操作和时间格式化等。
    • #calendars:用于更复杂时间的格式化。
    • #numbers:格式化数字对象的方法。
    • #aggregates:在数组或集合上创建聚合的方法。
    • #ids:处理可能重复的id属性的方法。

    9. body内的内联

    • 例子
    <!--内联标签的使用-->
        <!--内联写法1-->
        <p >[[|welcome to china,${text}|]]</p>
        <!--内联写法2-->
        <p>[('welcome to china,'+${text})]</p>
        <!--内联写法3-->
        <p>[('welcome to china')]</p>
    
    • 我们的习惯
      1.有时候这样更合适:<p>Hello,[[${session.user.name}]]</p>
      2.而不喜欢这样写代码:<p>Hello, <span th:text="${session.user.name]">Sebastian</span></p>

    • th属性和内联标签的对应关系
      1.[[...]]等价于th:text (结果将被HTML转义)
      2.[(...)]等价于th:utext(结果不会执行HTML转义)。

    • body上加上inline="none" 可以使内联失效

    <body th:inline="none">
    

    10. JS里的内联

    • 例子
    <script th:inline="javascript">
            var name = [[${name}]];
            var userName = [[${user.name}]];
            var userAge = [[${user.age}]];
            var userPass = [[${user.pass}]];
            alert("name:"+name+",userName:"+userName+",userAge:"
                +userAge+",userPass:"+userPass);
    </script>
    
    • 在JavaScript中使用内联标签(默认不支持)
      1.在script标签上引入对内联的支持:<script type="text/javascript" th:inline="javascript">
      2.在script标签里书写[[]]、[()]来获取后端数据;

    • 在JavaScript中实现前后端分离(也称之为JavaScript自然模板)
      1.Thymeleaf的目标就是希望前后端分离,即同一个Html文件前端人员以静态原型的方式打开时,看到的是它们的内容,而后端人员通过服务器打开时,看到的是动态的数据;
      2.直接在数据上使用js注释即可实现前后端分离: var msg =/*[[S{name]]*/'666666'
      3.当在服务器打开该页面时,就会展示${name}的值,当时在静态打开时,就展示666666

    • 在JavaScript中自动进行对象序列化
      1.JavaScript 内联的一个重要的特性是,内联表达式的计算结果不限于字符串,它能自动的将后台的数据序列化为javascript对象

    • Tips
      js中开启内联标签模式只能是在Html文件内部的JavaScript 代码,不能在引入的外部JavaScript文件中进行操作

    11. css里的内联

    • 例子
        <style type="text/css" th:inline="css" th:with="color='yellow',
            fontSize='25px'">
            p{
                /*这里是一个注释*/
                color: /*[[${color}]]*/ red;
                /*fontSize需要使用[()]来忽略HTML的转义*/
                font-size:[(${fontSize})];
            }
        </style>
    
    • 在CSS中使用内联标签(默认不支持)
      1.在style标签上引入对内联的支持: <style th:inline="css">
      2.在style标签里书写[[]][()]来获取后端数据;

    • 在CSS中实现前后端分离(也称之为CSS自然模板)
      1.与内联JavaScript一样,CSS内联也允许<style>标签可以静态和动态地工作,即通过在注释中包含内联表达式作为CSS自然模板。
      2.当服务器动态打开时,字体颜色为黄色;当以原型静态打开时,显示的是红色,因为Thymeleaf会自动忽略掉css注释之后和分号之前的代码。
      3.在CSS中,因为CSS自然模板的问题,所以不能在css中像以前一样添加注释,因为Thymeleaf会将它们当做模板进行处理。

    • Tips
      与内联JavaScript一样,内联CSS同样只能Html内嵌的<style >标签中进行使用,不能在外部关联的CSS文件中进行使用


    如果觉得有收获就点个赞吧,更多知识,请点击关注查看我的主页信息哦~

    相关文章

      网友评论

        本文标题:Thymeleaf的语法详情及使用

        本文链接:https://www.haomeiwen.com/subject/nvywyrtx.html