Thymeleaf 基本用法

hymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 JSP,Velocity,FreeMaker 等,它也可以轻易的与 Spring MVC 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

Thymeleaf 初探(原文位置 )

相比于其他的模板引擎,Thymeleaf 最大的特点是通过 HTML 的标签属性渲染标签内容,以下是一个 Thymeleaf 模板例子:

 

XHTML

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml"

      xmlns:th="http://www.thymeleaf.org">

 

  <head>

    <title>Good Thymes Virtual Grocery</title>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

    <link rel="stylesheet" type="text/css" media="all"

          href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" />

  </head>

 

  <body>

 

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

 

  </body>

 

</html>

 

这是一段标准的 HTML 代码,这也就意味着通过浏览器直接打开它是可以正确解析它的结构并看到页面的样子。相比去其他的模板引擎在指定的位置通过${}等表达式进行渲染,Thymeleaf 则是一种针对 HTML/XML 定制的模板语言(当然它可以被扩展),它通过标签中的th:text属性来填充该标签的一段内容。上例中,<p th:text="#{home.welcome}">Welcome to our grocery store!</p>意味着<p>标签中的内容会被表达式#{home.welcome}的值所替代,无论模板中它的内容是什么,之所以在模板中 “多此一举 “地填充它的内容,完全是为了它能够作为原型在浏览器中直接显示出来。

标准表达式语法

变量

Thymeleaf 模板引擎在进行模板渲染时,还会附带一个 Context 存放进行模板渲染的变量,在模板中定义的表达式本质上就是从 Context 中获取对应的变量的值:

XHTML

 

1

<p>Today is: <span th:text="${today}">13 february 2011</span>.</p>

假设today的值为2015年8月14日,那么渲染结果为:<p>Today is: 2015年8月14日.</p>。可见 Thymeleaf 的基本变量和 JSP 一样,都使用${.}表示获取变量的值。

URL

URL 在 Web 应用模板中占据着十分重要的地位,需要特别注意的是 Thymeleaf 对于 URL 的处理是通过语法@{...}来处理的。Thymeleaf 支持绝对路径 URL: 

XHTML

 

1

<a th:href="@{http://www.thymeleaf.org}">Thymeleaf</a>

同时也能够支持相对路径 URL:

  • 当前页面相对路径 URL——user/login.html,通常不推荐这样写。
  • Context 相关 URL——/static/css/style.css

另外,如果需要 Thymeleaf 对 URL 进行渲染,那么务必使用th:hrefth:src等属性,下面是一个例子

 

 

 

 

 

XHTML

 

1

2

3

4

5

6

7

8

9

<!-- Will produce 'http://localhost:8080/gtvg/order/details?orderId=3' (plus rewriting) -->

<a href="details.html"

   th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">view</a>

 

<!-- Will produce '/gtvg/order/details?orderId=3' (plus rewriting) -->

<a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a>

 

<!-- Will produce '/gtvg/order/3/details' (plus rewriting) -->

<a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>

几点说明:

  • 上例中 URL 最后的 (orderId=${o.id}) 表示将括号内的内容作为 URL 参数处理,该语法避免使用字符串拼接,大大提高了可读性
  • @{...}表达式中可以通过{orderId}访问 Context 中的orderId变量
  • @{/order}是 Context 相关的相对路径,在渲染时会自动添加上当前 Web 应用的 Context 名字,假设 context 名字为 app,那么结果应该是/app/order

如果 URLs 写在 style 的属性里,那么

 

XHTML

 

1

<div class="fill" style="background-image:url('../../style/images/bg_shadow_left.png');"></div>

替换写成 style 前面加 th: 链接的前后加上 + 号运算符,如下:

XHTML

 

1

<div class="fill" th:style="'background-image:url(' + @̣{/images/bg_shadow_left.png} + ');'"></div>

 

字符串替换

很多时候可能我们只需要对一大段文字中的某一处地方进行替换,可以通过字符串拼接操作完成:

XHTML

 

1

<span th:text="'Welcome to our application, ' + ${user.name} + '!'">

一种更简洁的方式是:

XHTML

 

1

<span th:text="|Welcome to our application, ${user.name}!|">

当然这种形式限制比较多,|...|中只能包含变量表达式${...},不能包含其他常量、条件表达式等。

运算符

在表达式中可以使用各类算术运算符,例如 +, -, *, /, %

XHTML

 

1

th:with="isEven=(${prodStat.count} % 2 == 0)"

逻辑运算符><<=,>===,!=都可以使用,唯一需要注意的是使用<,>时需要用它的 HTML 转义符:

XHTML

 

1

2

th:if="${prodStat.count} &gt; 1"

th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')"

循环

渲染列表数据是一种非常常见的场景,例如现在有 n 条记录需要渲染成一个表格<table>,该数据集合必须是可以遍历的,使用th:each标签:

XHTML

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<body>

  <h1>Product list</h1>

 

  <table>

    <tr>

      <th>NAME</th>

      <th>PRICE</th>

      <th>IN STOCK</th>

    </tr>

    <tr th:each="prod : ${prods}">

      <td th:text="${prod.name}">Onions</td>

      <td th:text="${prod.price}">2.41</td>

      <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>

    </tr>

  </table>

 

  <p>

    <a href="../home.html" th:href="@{/}">Return to home</a>

  </p>

</body>

可以看到,需要在被循环渲染的元素(这里是<tr>)中加入th:each标签,其中th:each="prod : ${prods}"意味着对集合变量prods进行遍历,循环变量是prod在循环体中可以通过表达式访问。

条件求值

If/Unless

Thymeleaf 中使用th:ifth:unless属性进行条件判断,下面的例子中,<a>标签只有在th:if中条件成立时才显示:

XHTML

 

1

<a th:href="@{/login}" th:unless=${session.user != null}>Login</a>

th:unlessth:if恰好相反,只有表达式中的条件不成立,才会显示其内容。

<a th:href="@{/login}" th:if=${session.user==null}>Login</a>

 

Switch

Thymeleaf 同样支持多路选择 Switch 结构:

 

 

 

 

 

XHTML

 

1

2

3

4

<div th:switch="${user.role}">

  <p th:case="'admin'">User is an administrator</p>

  <p th:case="#{roles.manager}">User is a manager</p>

</div>

默认属性 default 可以用*表示:

 

 

 

 

 

XHTML

 

1

2

3

4

5

<div th:switch="${user.role}">

  <p th:case="'admin'">User is an administrator</p>

  <p th:case="#{roles.manager}">User is a manager</p>

  <p th:case="*">User is some other thing</p>

</div>

 

Utilities

为了模板更加易用,Thymeleaf 还提供了一系列 Utility 对象(内置于 Context 中),可以通过#直接访问:

  • #dates
  • #calendars
  • #numbers
  • #strings
  • arrays
  • lists
  • sets
  • maps

下面用一段代码来举例一些常用的方法:

#dates

 

 

 

 

 

 

XHTML

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/*

* Format date with the specified pattern

* Also works with arrays, lists or sets

*/

${#dates.format(date, 'dd/MMM/yyyy HH:mm')}

${#dates.arrayFormat(datesArray, 'dd/MMM/yyyy HH:mm')}

${#dates.listFormat(datesList, 'dd/MMM/yyyy HH:mm')}

${#dates.setFormat(datesSet, 'dd/MMM/yyyy HH:mm')}

 

/*

* Create a date (java.util.Date) object for the current date and time

*/

${#dates.createNow()}

 

/*

* Create a date (java.util.Date) object for the current date (time set to 00:00)

*/

${#dates.createToday()}

 

#strings

 

 

 

 

 

 

XHTML

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

/*

* Check whether a String is empty (or null). Performs a trim() operation before check

* Also works with arrays, lists or sets

*/

${#strings.isEmpty(name)}

${#strings.arrayIsEmpty(nameArr)}

${#strings.listIsEmpty(nameList)}

${#strings.setIsEmpty(nameSet)}

 

/*

* Check whether a String starts or ends with a fragment

* Also works with arrays, lists or sets

*/

${#strings.startsWith(name,'Don')}                  // also array*, list* and set*

${#strings.endsWith(name,endingFragment)}           // also array*, list* and set*

 

/*

* Compute length

* Also works with arrays, lists or sets

*/

${#strings.length(str)}

 

/*

* Null-safe comparison and concatenation

*/

${#strings.equals(str)}

${#strings.equalsIgnoreCase(str)}

${#strings.concat(str)}

${#strings.concatReplaceNulls(str)}

 

/*

* Random

*/

${#strings.randomAlphanumeric(count)}

 

页面即原型

在 Web 开发过程中一个绕不开的话题就是前端工程师与后端工程师的协作,在传统 Java Web 开发过程中,前端工程师和后端工程师一样,也需要安装一套完整的开发环境,然后各类 Java IDE 中修改模板、静态资源文件,启动 / 重启 / 重新加载应用服务器,刷新页面查看最终效果。

但实际上前端工程师的职责更多应该关注于页面本身而非后端,使用 JSP,Velocity 等传统的 Java 模板引擎很难做到这一点,因为它们必须在应用服务器中渲染完成后才能在浏览器中看到结果,而 Thymeleaf 从根本上颠覆了这一过程,通过属性进行模板渲染不会引入任何新的浏览器不能识别的标签,例如 JSP 中的<form:input>,不会在 Tag 内部写表达式。整个页面直接作为 HTML 文件用浏览器打开,几乎就可以看到最终的效果,这大大解放了前端工程师的生产力,它们的最终交付物就是纯的 HTML/CSS/JavaScript 文件。

 

Thymeleaf 之 内置对象、定义变量、URL参数及标签自定义属性

如标题所述,这篇文章主要讲述Thymeleaf中的内置对象(list解析、日期格式化、数字格式化等)、定义变量、获取URL的参数和在页面标签中自定义属性的应用。

如果对Thymeleaf的基本使用、maven依赖等不清楚的可以先阅读我的另一篇文章《Thymeleaf 之 初步使用》

  • Controller部份
@Controller
public class IndexController {

    @GetMapping(value = "index")
    public String index(Model model, HttpServletRequest request) {
        List<String> datas = new ArrayList<String>();
        datas.add("知识林");
        datas.add("http://www.zslin.com");
        datas.add("393156105");
        model.addAttribute("datas", datas);
        model.addAttribute("curDate", new Date());

        model.addAttribute("money", Math.random()*100);
        return "index";
    }
}

在这个控制器的Model中存放了这样几个数据:一个String类型的列表、一个日期对象和一个数值,这些东西在实际应用开发过程中应用非常广泛,下面具体看一下在Thymeleaf中是如何解析这些数据的。

  • 日期格式化
<span th:text="${#dates.format(curDate, 'yyyy-MM-dd HH:mm:ss')}"></span>

说明: 使用内置对象datesformat函数即可对日期进行格式化,在format函数中,第一个参数是日期对象,对二两个参数为日期格式(规则跟SimpleDateFormat一样)

需要注意的是:

· 内置对象一般都以s结尾,如dateslistsnumbers

· 在使用内置对象是在对象名前都需要加#号。

  • 数字格式化
<span th:text="${#numbers.formatDecimal(money, 0, 2)}"></span>

说明: 此示例表示保留两位小数位,整数位自动;

<span th:text="${#numbers.formatDecimal(money, 3, 2)}"></span>

说明: 此示例表示保留两位小数位,3位整数位(不够的前加0)

  • 获取列表长度
<span th:text="${#lists.size(datas)}"></span>

说明: 使用#lists.size来获取List的长度。

  • 获取URL参数值
<span th:text="${#httpServletRequest.getParameter('page')}"></span>

说明: 当访问http://localhost:1105/index?page=5时页面将会得到page对应的值:5

  • 定义变量
<div th:with="curPage=${#httpServletRequest.getParameter('page')}">
    <h3>当前页码:<span th:text="${curPage}"></span></h3>
</div>

说明: 同样,当访问http://localhost:1105/index?page=5时,页面将显示:当前页码:5,说明用th:with来定义变量,多个用,号隔开,使用范围在当前标签内。

  • 自定义标签属性

Thymeleaf中可以使用th:加上标签的任何属性进行赋值,但有些时候会遇到自定义的属性,再用th:加自定义的属性则会无效。比如:需要对<span>标签增加objNameobjId这样的属性,在非Thymeleaf情况下是这样:

<span objId="1" objName="知识林"></span>

变量情况是:

<span objId="${obj.id}" objName="${obj.name}"></span>

Thymeleaf下则是:

<span th:attr="myDate=${#dates.format(curDate, 'yyyy-MM-dd')}, myMoney=${money}"></span>

说明: 在页面上查看源代码可以看到:<span myMoney="91.6059494319957" myDate="2016-31-02"></span>,说明自定义属性用:th:attr,多个属性用,隔开。

  • 内置对象

上面简单描述了比较常用的dateslistsnumbers这几个内置对象,在Thymeleaf还有很多的内置对象,像strings也非常常用,用法跟java.lang.String类的用法一样。

Thymeleaf中的内置对象有:

#dates:日期格式化内置对象,具体方法可以参照java.util.Date

#calendars:类似于#dates,但是是java.util.Calendar类的方法;

#numbers: 数字格式化;

#strings:字符串格式化,具体方法可以参照java.lang.String,如startsWithcontains等;

#objects:参照java.lang.Object

#bools:判断boolean类型的工具;

#arrays:数组操作的工具;

#lists:列表操作的工具,参照java.util.List

#sets:Set操作工具,参照java.util.Set

#maps:Map操作工具,参照java.util.Map

#aggregates:操作数组或集合的工具;

#messages:操作消息的工具。

thymeleaf+bootstrap,onclick传参

<span title="删除"
      th:onclick="'javascript:delCfmModel(\'/user/' + ${user.id} + '/delete\')'"
      style="cursor: pointer"
      class="glyphicon glyphicon-trash">
</span>

或 使用字符串拼接的另外一种简洁写法:<span th:text="|Welcome to our application, ${user.name}!|">

<span title="删除"
    th:onclick="|javascript:delCfmModel('/sys/user/${user.id}/delete')|"
      style="cursor: pointer"
      class="glyphicon glyphicon-trash">
</span>


 

如果参数是字符串,需要加引号,如上图所示。否则会报错:Uncaught SyntaxError:Invalid regular expressiong flags

如果只传数字,可以不加引号,如下图所示:

复制代码

<a href="#editModal"
   role="button"
   data-toggle="modal"
   th:onclick="'javascript:editUser('+${prod.id}+');'">
    Edit
</a>
<script>
    function editUser(id) {
        $.get("/projectName/user/edit",
                {objectid: id},
                function (data) {
                    $("#frm_container1").html(data);
                });
    }
</script>

复制代码

https://yq.aliyun.com/articles/60696

 

复制代码

<!-- 信息删除确认 -->
<div class="modal fade" id="deleteModal">
    <div class="modal-dialog">
        <div class="modal-content message_align">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">×</span>
                </button>
                <h4 class="modal-title">Delete</h4>
            </div>
            <div class="modal-body" style="text-align: center">
                <p>
                    <i class="glyphicon glyphicon-alert"></i>
                    Do You Really Want to Delete This?
                </p>
            </div>
            <div class="modal-footer">
                <input type="hidden" id="modalUrl"/>
                <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
                <a id="modalConfirmBtn" class="btn btn-success" data-dismiss="modal">Delete</a>
            </div>
        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

复制代码

复制代码

<script type="text/javascript">

    function delCfmModel(url) {
        $('#modalUrl').val(url);//给会话中的隐藏属性URL赋值
        $('#deleteModal').modal();
    }

    $("#modalConfirmBtn").click(function () {
        $.get($('#modalUrl').val(),function () {
            window.location.reload(); //重新加载页面
        });
    });
</script>

复制代码

 如果需要弹出的Modal窗口垂直居中,水平居中,可以添加以下css样式(这个样式是覆盖了bootstrap的。tips,这个css是为上面的Modal div深度定制的,如需更改,需确定上面的html是否同步更改)

复制代码

        .modal {
            text-align: center;
        }

        @media screen and (min-width: 768px) {
            .modal:before {
                display: inline-block;
                vertical-align: middle;
                content: " ";
                height: 100%;
            }
        }

        .modal-dialog {
            display: inline-block;
            text-align: left;
            vertical-align: middle;
        }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值