模板引擎thymeleaf

引入

在maven中引入:

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

在html標籤下引入:

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

變量表達式${}

變量表達式即 OGNL 表達式或 Spring EL 表達式(在 Spring 術語中也叫 model attributes)。語法爲: ${session.user.name}

它們將以HTML標籤的一個屬性來表示:

<span th:text="${book.author.name}">  
<li th:each="book : ${books}">  

文字國際化表達式

文字國際化表達式允許我們從一個外部文件獲取區域文字信息(.properties),用 Key 索引 Value,還可以提供一組參數(可選).

#{main.title}  
#{message.entrycreated(${entryId})}  

可以在模板文件中找到這樣的表達式代碼:

<table>  
  ...  
  <th th:text="#{header.address.city}">...</th>  
  <th th:text="#{header.address.country}">...</th>  
  ...  
</table>  

URL 表達式@{}

URL 表達式指的是把一個有用的上下文或回話信息添加到 URL,這個過程經常被叫做 URL 重寫。加載圖片時用到@{},如 @{/order/list}

URL還可以設置參數:@{/order/details(id=${orderId})}

相對路徑:@{../documents/report}

<form th:action="@{/createOrder}">  
<a href="main.html" th:href="@{/main}">

星號表達式*{}

星號語法評估在選定對象上表達,而不是整個上下文,選定對象就是父標籤的值,如下:

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

這是完全等價於:

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

常用th標籤

<th:if>

用在標籤內表示if 語句,如果表達式成立則渲染語句,否則不渲染,最常用的直接使用${},如果{}中的語句成立則執行數據渲染,如:

<li th:if="${customer!=null}">
    <a class="dropdown-button" href="#!" data-activates="dropdown1">
    <img class="responsive-img circle " src="/mall/image/風.jpg" style="width: 50px;height: 50px">
     <i class="material-icons right">arrow_drop_down</i></a>
</li>
<li th:if="${customer==null}">
      <a class="waves-effect waves-light btn">登錄/註冊</a>
</li>

如果想使用外部條件進行某些判斷,可使用符號縮寫,表達式中內置的值爲:

gt:great than(大於)>
ge:great equal(大於等於)>=
eq:equal(等於)==
lt:less than(小於)<
le:less equal(小於等於)<=
ne:not equal(不等於)!=

示例:

<span th:if="${index} gt '7'"></span>
<a th:if="${order.state} eq '已發貨'" class="btn">已發貨</a>
<a th:if="${order.state} eq '未發貨'" class="btn" th:onclick="updateOrder([[${order.id}]])">設置爲已發貨</a>

<th:each>

用於迭代集合

<table>
   <thead>
      <tr>
         <th>序號</th>
         <th>用戶名</th>
         <th>密碼</th>
         <th>用戶暱稱</th>
      </tr>
      <tr th:each="user:${userlist}">
         <td th:text="${user.id}"></td>
         <td th:text="${user.username}"></td>
         <td th:text="${user.password}"></td>
         <td th:text="${user.petname}"></td>
      </tr>
   </thead>
</table>

th:each屬性用於迭代循環,語法:th:each=“obj,iterStat:${objList}”

迭代對象可以是java.util.List,java.util.Map,數組等;

obj就是迭代對象

iterStat稱作狀態變量,屬性有:
index:當前迭代對象的index(從0開始計算)
count: 當前迭代對象的index(從1開始計算)
size:被迭代對象的大小
current:當前迭代變量
even/odd:布爾值,當前循環是否是偶數/奇數(從0開始計算)
first:布爾值,當前循環是否是第一個
last:布爾值,當前循環是否是最後一個

<div th:each="depository:${depositoryMap}">
                <div class="section">
                    <div class="row" >
                        <div class="col s9">
                            <div class="row">
                                <div class="col s4">名稱:<p th:text="${depository.value.name}"></p> </div>
                                <div class="col s4">庫存量:<p th:text="${depository.key.count}"></p> </div>
                                <div class="col s4">現價:<p th:text="${depository.value.discountPrice}"></p></div>

js中使用後臺的傳值

js通過model取值

<script th:inline="javascript">
    var message = [[${message}]];
    console.log(message);
</script>

注:script標籤中 th:inline 一定不能少,通常在取值的前後會加上不同的註釋

th:onclick向js函數中傳遞參數

使用th:onclick,進行字符串的拼接

<a class="waves-effect waves-light btn col s4" th:onclick="'javascript:addToCart('+${book.id}+','+${book.name}+','+${book.discountPrice}+','+${book.imgs}+')' ">加入購物車</a>

報錯:Only variable expressions returning numbers or booleans are allowed in this context, any other datatypes are not trusted in the context of this expression, including Strings or any other object that could be rendered as a text literal. A typical case is HTML attributes for event handlers (e.g. “onload”), in which textual data from variables should better be output to “data-*” attributes and then read from the event handl

只允許數字或者boolean

嘗試第二種:自定義id進行拼接:

<a class="waves-effect waves-light btn col s4" th:name-id="${book.name}" th:imgs-id="${book.imgs}" th:onclick="'javascript:addToCart('+${book.id}+','+this.getAttribute('name-id')+','+${book.discountPrice}+','+this.getAttribute('imgs-id')+')'">加入購物車</a>

還是無效,嘗試第三種:[[]]包裹

<a class="waves-effect waves-light btn col s4" th:onclick="addToCart([[${book.id}]],[[${book.name}]],[[${book.discountPrice}]],[[${book.imgs}]])">加入購物車</a>

這回可以正常解析

在js中賦值(null情況)

EL表達式相當於寫代碼,爲了判斷空可以使用判斷運算符,否則引用null會解析出錯

var customerId=[[${customer==null?0:customer.id}]];

常用的使用方法

1、賦值、字符串拼接

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

字符串拼接還有另外一種簡潔的寫法

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

2、for 循環

<tr th:each="collect,iterStat : ${collects}"> 
   <th scope="row" th:text="${collect.id}">1</th>
   <td >
      <img th:src="${collect.webLogo}"/>
   </td>
   <td th:text="${collect.url}">Mark</td>
   <td th:text="${collect.title}">Otto</td>
   <td th:text="${collect.description}">@mdo</td>
   <td th:text="${terStat.index}">index</td>
</tr>

iterStat稱作狀態變量,屬性同<th:each>中解析的一樣

3、內嵌變量

爲了模板更加易用,Thymeleaf 還提供了一系列 Utility 對象(內置於 Context 中),可以通過 # 直接訪問:

  • dates : java.util.Date的功能方法類。
  • calendars : 類似#dates,面向java.util.Calendar
  • numbers : 格式化數字的功能方法類
  • strings : 字符串對象的功能類,contains,startWiths,prepending/appending等等。
  • objects: 對objects的功能類操作。
  • bools: 對布爾值求值的功能方法。
  • arrays:對數組的功能類方法。
  • lists: 對lists功能類方法
  • sets
  • maps

下面用一段代碼來舉例一些常用的方法:

dates

/*
 * 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

/*
 * 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)}

使用 Thymeleaf 佈局

Spring Boot 2.0 將佈局單獨提取了出來,需要單獨引入依賴:thymeleaf-layout-dialect。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>nz.net.ultraq.thymeleaf</groupId>
    <artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>

定義代碼片段

<footer th:fragment="copy"> 
&copy; 2019
</footer>

在頁面任何地方引入:

<body>
    <div th:insert="layout/copyright :: copyright"></div>
    <div th:replace="layout/copyright :: copyright"></div>
</body>

th:insert 和 th:replace 區別,insert 只是加載,replace 是替換。Thymeleaf 3.0 推薦使用 th:insert 替換 2.0 的 th:replace。

返回的 HTML 如下:

<body> 
  <div> &copy; 2019 </div> 
  <footer>&copy; 2019 </footer> 
</body>

下面是一個常用的後臺頁面佈局,將整個頁面分爲頭部,尾部、菜單欄、隱藏欄,點擊菜單隻改變 content 區域的頁面,content是可外部引用的佈局

<body class="layout-fixed">
  <div th:fragment="navbar"  class="wrapper"  role="navigation">
    <div th:replace="fragments/header :: header">Header</div>
    <div th:replace="fragments/left :: left">left</div>
    <div th:replace="fragments/sidebar :: sidebar">sidebar</div>
    <div layout:fragment="content" id="content" ></div>
    <div th:replace="fragments/footer :: footer">footer</div>
  </div>
</body>

任何頁面想使用這樣的佈局只需要替換content 模塊即可

<html xmlns:th="http://www.thymeleaf.org" layout:decorator="layout">
 <body>
    <section layout:fragment="content">
  ...

也可以在引用模版的時候傳參

<head th:include="layout :: htmlhead" th:with="title='Hello'"></head>

layout 是文件地址,如果有文件夾可以這樣寫fileName/layout:htmlhead,htmlhead 是指定義的代碼片段 如th:fragment="copy"

<h4 class="media-heading" th:inline="text">[[${question.title}]]
    <a th:href="@{'/question/'+${question.id}}" th:text="${question.title}"></a>
 </h4>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章