zoukankan      html  css  js  c++  java
  • 前端渲染模板(一):Thymeleaf

    一、使用

      本篇文章将以SpringBoot为框架来介绍Thymeleaf的用法。

      1 资源文件的约定目录结构 

    Maven的资源文件目录:/src/java/resources
    spring-boot项目静态文件目录:/src/java/resources/static
    spring-boot项目模板文件目录:/src/java/resources/templates
    spring-boot静态首页的支持,即index.html放在以下目录结构会直接映射到应用的根目录下:

    classpath:/META-INF/resources/index.html
    classpath:/resources/index.html
    classpath:/static/index.html
    calsspath:/public/index.html

      因此,SpringBoot默认的静态资源文件应该放在resources/tatic下,而静态页面应该放在resources/templates文件夹下,这两个文件不会自动创建,需要手动创建,如下图所示:

                                                                                                                                  

      2 Maven依赖:

    1         <!-- thymeleaf 前端渲染模板依赖 -->
    2         <dependency>
    3             <groupId>org.springframework.boot</groupId>
    4             <artifactId>spring-boot-starter-thymeleaf</artifactId>
    5             <version>2.0.0.RELEASE</version>
    6         </dependency>

      3 html页面中(<html>标签处):

    1 <html xmlns="http://www.w3.org/1999/xhtml"
    2       xmlns:th="http://www.thymeleaf.org"
    3       xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">

      4 application.properties配置(application.yml则根据格式相应变化即可):

     1 # THYMELEAF (ThymeleafAutoConfiguration)  
     2 #开启模板缓存(默认值:true)  
     3 spring.thymeleaf.cache=true   
     4 #Check that the template exists before rendering it.  
     5 spring.thymeleaf.check-template=true  
     6 #检查模板位置是否正确(默认值:true)  
     7 spring.thymeleaf.check-template-location=true  
     8 #Content-Type的值(默认值:text/html)  
     9 spring.thymeleaf.content-type=text/html  
    10 #开启MVC Thymeleaf视图解析(默认值:true)  
    11 spring.thymeleaf.enabled=true  
    12 #模板编码  
    13 spring.thymeleaf.encoding=UTF-8  
    14 #要被排除在解析之外的视图名称列表,用逗号分隔  
    15 spring.thymeleaf.excluded-view-names=  
    16 #要运用于模板之上的模板模式。另见StandardTemplate-ModeHandlers(默认值:HTML5)  
    17 spring.thymeleaf.mode=HTML5  
    18 #在构建URL时添加到视图名称前的前缀(默认值:classpath:/templates/)  
    19 spring.thymeleaf.prefix=classpath:/templates/  
    20 #在构建URL时添加到视图名称后的后缀(默认值:.html)  
    21 spring.thymeleaf.suffix=.html  
    22 #Thymeleaf模板解析器在解析器链中的顺序。默认情况下,它排第一位。顺序从1开始,只有在定义了额外的TemplateResolver Bean时才需要设置这个属性。  
    23 spring.thymeleaf.template-resolver-order=  
    24 #可解析的视图名称列表,用逗号分隔  
    25 spring.thymeleaf.view-names=  

      配置好以上的代码,此时在html模板文件中动态的属性使用th:命名空间修饰,就可以使用Thymeleaf了。

    二、语法

      1 引用静态资源文件:

        比如CSS和JS文件,语法格式为“@{}”,如@{/js/blog/blog.js}会引入/static目录下的/js/blog/blog.js文件。

      2 访问spring-mvc中model的属性:

        语法格式为“${}”,如${user.id}可以获取model里的user对象的id属性,类似JSTL。

      3 循环:

        在html的标签中,加入th:each=“value:${list}”形式的属性,如<span th:each=”user:${users}”></span>可以迭代users的数据

      4 判断:    

    在html标签中,加入th:if=”表达式”可以根据条件显示html元素

    1 <span th:if="${not #lists.isEmpty(blog.publishTime)}"> 
    2   <span id="publishtime" th:text="${#dates.format(blog.publishTime, 'yyyy-MM-dd HH:mm:ss')}"></span> 
    3 </span> 

    以上代码表示若blog.publishTime时间不为空,则显示时间。

    5 时间格式化:

    1 ${#dates.format(blog.publishTime,'yyyy-MM-dd HH:mm:ss')} //表示将时间格式化为”yyyy-MM-dd HH:mm:ss”格式化写法与Java格式化Date的写法是一致的。 

      6 字符串拼接:

        有两种形式 ,比如拼接这样一个URL:/blog/delete/{blogId} 

    第一种:th:href="'/blog/delete/' + ${blog.id }"
    第二种:th:href="${'/blog/delete/' + blog.id }"

    7 为CSS样式的某些路径使用thyemleaf表达式:

    1 <div th:style="'background:url(' + @{/<path-to-image>} + ');'"></div>

       8 使用th:utext="@{}" 可以让变量里面的html标签被解析

    三、表达式

      1 简单表达式 (simple expressions)

    1   ${...} 变量表达式
    2 
    3   *{...} 选择变量表达式
    4 
    5   #{...} 消息表达式
    6 
    7   @{...} 链接url表达式

      2 字面量

    1   'one text','another one!',... 文本
    2 
    3   0,34,3.0,12.3,... 数值
    4 
    5   true false 布尔类型
    6 
    7   null 空
    8 
    9   one,sometext,main 文本字符

      3 文本操作

    1   + 字符串连接
    2 
    3   |The name is ${name}| 字符串连接

      4 算术运算

    1   + , - , * , / , % 二元运算符
    2 
    3   - 负号(一元运算符)

      5 布尔操作

    1   and,or 二元操作符
    2 
    3   !,not 非(一元操作符)

      6 关系操作符

    1   > , < , >= , <= (gt , lt , ge , le)
    2 
    3   == , != (eq, ne)

      7 条件判断

    1 (if) ? (then) if-then
    2 
    3 (if) ? (then) : (else) if-then-else
    4 
    5 <tr th:class="${row.even}? 'even' : 'odd'">
    6 ...
    7 </tr>

    条件表达式中的三个部分自身也可以是表达式,也可以是变量(${...}, *{...}), 消息(#{...}), URL (@{...}) 或字面量 ('...')
    条件表达式也可以使用括号来嵌套:

    1 <tr th:class="${row.even}? (${row.first}? 'first' : 'even') : 'odd'">
    2 ...
    3 </tr>

      else表达式也可以省略,当条件为false时,会返回null:

    1 <tr th:class="${row.even}? 'alt'">
    2 ...
    3 </tr>
    4 (value) ?: (defaultvalue) Default

      只有在第一个表达式返回null时,第二个表达式才会运算

      8 表达式工具对象

     1 #dates 与java.util.Date对象的方法对应,格式化、日期组件抽取等等
     2 #calendars 类似#dates,与java.util.Calendar对象对应
     3 #numbers 格式化数字对象的工具方法
     4 #strings 与java.lang.String对应的工具方法:contains、startsWith、prepending/appending等等
     5 #objects 用于对象的工具方法
     6 #bools 用于布尔运算的工具方法
     7 #arrays 用于数组的工具方法
     8 #lists 用于列表的工具方法
     9 #sets 用于set的工具方法
    10 #maps 用于map的工具方法
    11 #aggregates 用于创建数组或集合的聚合的工具方法
    12 #messages 用于在变量表达式内部获取外化消息的工具方法,与#{…}语法获取的方式相同
    13 #ids 用于处理可能重复出现(例如,作为遍历的结果)的id属性的工具方法

      9 链接URL

    URL在web模板中是一级重要元素,使用@{…}表示

    URL的类型:

      绝对URL:

    http://www.thymeleaf.org

      相对URL:

    1 页面相对: user/login.html
    2 上下文相对:/itemdetails?id=3 (服务器上下文名称会被自动添加)
    3 服务器相对:~/billing/processInvoice(允许调用同一服务器上的另一个上下文中的URL)
    4 协议相对://code.jquery.com/jquery-2.0.3.min.js

    Thymeleaf在任何情况下都可以处理绝对URL,对于相对URL,则需要使用一个实现了IWebContext接口的上下文对象,这个对象包含了来自HTTP请求的信息,这些信息用于创建相对链接。

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

      10 预处理
      Thymeleaf提供预处理表达式的功能。

    它是在表壳式正常执行前执行的操作,允许修改最终将要被执行的表达式。

    预处理表达式跟正常的一样,但被两个下划线包围住,例如:__${expression}__

    假设有一个i18n消息文件Message_fr.properties,里面有一个条目包含了一个调用具体语言的静态方法的OGNL表达式:

    article.text=@myapp.translator.Translator@translateToFrench({0})

      Messages_es.properties中的等价条目:

    article.text=@myapp.translator.Translator@translateToSpanish({0})

      可以根据locale先创建用于运算表达式的标记片段,本例中,先通过预处理选择表达式,然后让Thymeleaf处理这个选择出来的表达式:

    <p th:text="${__#{article.text('textVar')}__}">Some text here...</p>

      对于locale为French的情况,上面的表达式经过预处理后,得出的等价物如下:

    <p th:text="${@myapp.translator.Translator@translateToFrench(textVar)}">Some text here...</p>

    四、 设置属性值

      1 th:attr 任何属性值

    1 <form action="subscribe.html" th:attr="action=@{/subscribe}">
    2   <fieldset>
    3     <input type="text" name="email" />
    4     <input type="submit" value="Subscribe me!" th:attr="value=#{subscribe.submit}"/>
    5   </fieldset>
    6 </form>

      多个属性一起设置,用逗号隔开

    <img src="../../images/gtvglogo.png" th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />

      2 设置指定属性

    th:abbr
    th:accept
    th:accept-charset th:accesskey
    th:action
    th:align th:alt
    th:archive
    th:audio th:autocomplete
    th:axis
    th:background th:bgcolor
    th:border
    th:cellpadding th:cellspacing
    th:challenge
    th:charset th:cite
    th:class
    th:classid ...
    1 <input type="submit" value="Subscribe me!" th:value="#{subscribe.submit}"/>
    2 <form action="subscribe.html" th:action="@{/subscribe}">
    3 <li><a href="product/list.html" th:href="@{/product/list}">Product List</a></li>

      设置多个属性在同一时间 有两个特殊的属性可以这样设置: th:alt-title 和 th:lang-xmllang

    th:alt-title 设置 alt 和 title
    th:lang-xmllang 设置 lang 和 xml:lang

    1 <img src="../../images/gtvglogo.png" th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />
    2 
    3 <img src="../../images/gtvglogo.png"th:src="@{/images/gtvglogo.png}" th:title="#{logo}" th:alt="#{logo}" />
    4 
    5 <img src="../../images/gtvglogo.png"th:src="@{/images/gtvglogo.png}" th:alt-title="#{logo}" />

      前置和后置添加属性值 th:attrappend 和 th:attrprepend

    <input type="button" value="Do it!" class="btn" th:attrappend="class=${' ' + cssStyle}" />

      编译后:

    <input type="button" value="Do it!" class="btn warning" />

      还有两个特定的添加属性 th:classappend 和 th:styleappend

    <tr th:each="prod : ${prods}" class="row" th:classappend="${prodStat.odd}? 'odd'">

      3 修复的布尔属性

    <input type="checkbox" name="active" th:checked="${user.active}" />

      所有修复的布尔属性:

    th:async 
    th:autofocus
    th:autoplay
    th:checked
    th:controls
    th:declare
    th:default
    th:defer
    th:disabled
    th:formnovalidate
    th:hidden
    th:ismap
    th:loop
    th:multiple
    th:novalidate
    th:nowrap
    th:open
    th:pubdate
    th:readonly
    th:required
    th:reversed
    th:scoped
    th:seamless
    th:selected

      HTML5友好的属性及元素名

    1 <table>
    2 <tr data-th-each="user : ${users}">
    3 <td data-th-text="${user.login}">...</td>
    4 <td data-th-text="${user.name}">...</td>
    5 </tr>
    6 </table>

      注:data-{prefix}-{name}是编写HTML5自定义属性的标准语法,不需要开发者使用th:*这样的命名空间,Thymeleaf让这种语法自动对所有dialect都可用。

    五、遍历

      1 基础

    1 <tr th:each="prod : ${prods}">
    2   <td th:text="${prod.name}">Onions</td>
    3   <td th:text="${prod.price}">2.41</td>
    4   <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
    5 </tr>

      可遍历的对象:实现java.util.Iterable、java.util.Map(遍历时取java.util.Map.Entry)、array、任何对象都被当作只有对象自身一个元素的列表

      2 状态

    当前遍历索引,从0开始,index属性
    当前遍历索引,从1开始,count属性
    总元素数量,size属性
    每一次遍历的iter变量,current属性
    当前遍历是even还是odd,even/odd布尔属性
    当前遍历是第一个,first布尔属性
    当前遍历是最后一个,last布尔属性

    1 <tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'">
    2   <td th:text="${prod.name}">Onions</td>
    3   <td th:text="${prod.price}">2.41</td>
    4   <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
    5 </tr>

    若不指定状态变量,Thymeleaf会默认生成一个名为“变量名Stat”的状态变量:

    1 <tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'">
    2   <td th:text="${prod.name}">Onions</td>
    3   <td th:text="${prod.price}">2.41</td>
    4   <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
    5 </tr>

    六、条件运算

    1 <tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'">
    2   <td th:text="${prod.name}">Onions</td>
    3   <td th:text="${prod.price}">2.41</td>
    4   <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
    5   <td>
    6     <span th:text="${#lists.size(prod.comments)}">2</span> comment/s
    7     <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:if="${not #lists.isEmpty(prod.comments)}">view</a>
    8   </td>
    9 </tr>
    <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:if="${not #lists.isEmpty(prod.comments)}">view</a>

      th:if 不只运算布尔条件,它对以下情况也运算为true:

      值不为null
        值为boolean且为true
        值为数字且非0
        值为字符且非0
        值是字符串且不是:“false”,“off”,“no”
        值不是boolean、数字、字符、字符串
      如果值为null,则th:if运算结果为false

      th:if的反面是th:unless

     1 <a href="comments.html" th:href="@{/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">view</a>
     2 th:switch 和 th:case
     3 
     4 <div th:switch="${user.role}">
     5   <p th:case="'admin'">User is an administrator</p>
     6   <p th:case="#{roles.manager}">User is a manager</p>
     7 </div>
     8 
     9 <div th:switch="${user.role}">
    10   <p th:case="'admin'">User is an administrator</p>
    11   <p th:case="#{roles.manager}">User is a manager</p>
    12   <p th:case="*">User is some other thing</p>
    13 </div>

    七、坑

      总结一下在使用过程中遇到的坑:

      1 获取项目根目录,很多时候我们都需要获取本项目的根目录,但是使用的代码是以下代码才能获得:

    <script th:inline="javascript" type="text/javascript">
        var ctx=[[${#httpServletRequest.getContextPath()}]];
    </script>

       注意以上代码,如果需要在自定义的javascript中使用thymeleaf表达式,则需要将script声明一下:th:inline="javascript"。

      2 获取图片路径,当我们使用thymeleaf的时候一定要注意单、双引号的区别,不然是无法获取到对应的值或者路径的:

    <span class="img" th:style="'background-image: url('+@{/images/news/}+${top4News[2].originArticleId}+'/1.jpg'+');'"></span>

       请注意以上代码:当我们要在backgroud-image这个标签下引用对应路径的img时:

        首先使用th:style进行修饰。

        然后在background-image标签前后一定要加单引号,否则不会起作用:

    'background-image:xxx'

         接着就是在url里面拼接你的img路径,请注意url('xxx'),也有单引号!

        最后才能通过此路径获取到相应的图片。

    八、总结

      在使用thymeleaf的过程中,遇到了一些坑,希望大家在这样的坑中少走一些弯路。

  • 相关阅读:
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    redis被攻击,怎么预防
    Redis3.2.12单节点安装
    Linux安装Redis、后台运行、系统自启动
    Redis 密码设置和查看密码
    Redis protected-mode属性解读
    SpringCloud(9)----mysql实现配置中心
    SpringCloud(8)----zuul权限校验、接口限流
  • 原文地址:https://www.cnblogs.com/laowangc/p/8884074.html
Copyright © 2011-2022 走看看