iT邦幫忙

2021 iThome 鐵人賽

DAY 14
1

Thymeleaf 是Spring Boot 推薦使用的前端模板引擎,它除了可以完全取代JSP 外,還有以下三個優點。

  1. Thymeleaf 支援HTML 原型並在HTML 標籤增加額外的屬性來達到模板資料的展示方式,這使得它不管在有網路或無網路的環境下都可以運行。
    因為瀏覽器解析HTML 時會忽略未定義的標籤屬性,所以可以在瀏覽器檢視頁面的靜態效果,也因為當有資料返回到頁面時,Thymeleaf 會動態地替換掉靜態內容,所以也可以在伺服器檢視帶有資料的動態效果。
  2. Thymeleaf 有開箱即用的特性,它提供標準(Standard dialects)和Spring 標準(Spring Standard dialects)兩種方言,可以直接套用模板實現JSTL、OGNL 表示式效果,避免每天套模板、改標籤等困擾,同時開發人員也可以創建自定義的標籤。
  3. Thymeleaf 提供Spring 標準方言和Spring MVC 完美集成的可選模塊,可以快速的實現表單綁定、屬性編輯器、國際化等功能。

常用表達式

變量表達式

變量表達式即OGNL 表達式或Spring EL 表達式,傳入控制器設定的name 值

<span th:text="${name}"></span>

選擇表達式

選擇表達式跟變量表達式很像,不過它是用一個預先選擇的對象來取代上下文變數容器執行

<div th:Object="${book}">
	...
	<span>[[*{title}]]</span>
	...
</div>

文字國際化表達式

文字國際化表達式允許我們從一個外部檔案獲取文字資訊,通過鍵值來引用文字訊息,在Spring 中,可自動與Spring 的MessageSource 機制集成。

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

若希望表達式由上下文變量的值決定,或希望將變量指定為參數,則可以在表達式中使用變量表達式。

#{${config.adminWelcomeKey}(${session.user.name})}

URL 表達式

URL 表達式指的是把一個有用的上下文或回話資訊新增到URL,這個過程經常被叫做URL 重寫。

<link rel="stylesheet" th:href="@{/css/reset.css}">

可以設定參數

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

其結果為

<a href="/order/details?id=1">...</a>

也可以為相對路徑,但應用程式上下文不會被加到URL 前面

<a th:href="@{../documents/report}"></a>

還可以是與伺服器的相對路徑,同樣應用程式上下文不會被加到URL 前面

<a th:href="@{~/contents/main}"></a>

當然,也可以設定為絕對路徑

<a th:href="@{http://www.mycompany.com/main}">...</a>

常用標籤

因為標籤的使用方法大多為th: 加上HTML 標籤後再交由表達式賦值或判斷,因次這邊只列出比較特殊的使用範例。

物件操作

  1. th:object : 用於接收後台傳過來的物件
  2. th:field : 用於綁定後台物件和表單資料,可同時設定id 和name 為後台物件屬性,且value 為該屬性值。
<form th:object="${user}">
	<input th:field="*{account}"/>
	<input th:field="*{password}"/>
</form>

HTML 解析結果如下

<form>
	<input id="account" name="account" value="account"/>
	<input id="password" name="password" value="password"/>
</form>

共用程式區塊

  1. th:fragment : 標記重複程式區塊。
    假設有一區塊設定為block.html,其內容為

    <div th:fragment="block">
    	<h1>Thymeleaf Block</h1>
    </div>
    
  2. th:insert : 區塊插入所屬標籤中。

    <section th:insert="block :: block"></section>
    

    效果為

    <section>
    	<div>
    		<h1>Thymeleaf Block</h1>
    	</div>
    </section>
    
  3. th:replace : 區塊取代所屬標籤。

    <section th:replace="block :: block"></section>
    

    效果為

    <div>
    	<h1>Thymeleaf Block</h1>
    </div>
    
  4. th:include : 區塊內容插入所屬標籤中(3.0 開始不建議使用)。

    <section th:include="block :: block"></section>
    

    效果為

    <section>
    	<h1>Thymeleaf Block</h1>
    </section>
    

迴圈

th:each : 遍歷整個List 或Array 物件。

<select th:each="item : ${list}">
	<option th:value="${item.value}">[[${item.name}]]</option>
</select>

條件判斷

  1. th:if : 條件成立時顯示。
  2. th:unless : 條件不成立時顯示。
    假設有一條件為判斷User 是否存在
<div>
	<span th:if="${user == null}">User 不存在</span>
	<span th:unless="${user == null}">User 存在</span>
</div>

當User 存在時,效果為

<div>
	<span>User 存在</span>
</div>
  1. Switch 判斷

    1. th:switch : 多選擇判斷,指定case 判斷變數。
    2. th:case : 判斷switch 指定變數為何。
      假設有一條件為判斷User 權限為何
    <div th:switch="${user.role}">
    	<span th:case="admin">管理員</span>
    	<span th:case="vip">VIP 會員</span>
    	<span th:case="*">普通會員</span>
    </div>
    

    當User 的role 不為admin 或vip 時,效果為

    <div>
    	<span>普通會員</span>
    </div>
    

實作

新增依賴

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

配置Thymeleaf 屬性

# 表示是否啟用Thymeleaf 的快取
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.resources.static-locations=classpath:/static/

CSS 共同資源

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="css">
    <link rel="stylesheet" th:href="@{/css/reset.css}">
    <link rel="stylesheet" th:href="@{/css/main.css}">
</head>
</html>

JS 共同資源

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="js">
    <script th:src="@{/js/lib/jquery-3.4.1.js}"></script>
    <script th:src="@{/js/validation.js}"></script>
</head>
</html>

登入頁面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>會員登入</title>
    <head th:insert="load/css :: css"></head>
    <head th:insert="load/js :: js"></head>
    <link rel="stylesheet" th:href="@{/css/login.css}">
</head>
<body>
    <main>
        <h1>會員登入</h1>
        <form id=loginForm method="POST" th:action="@{/login}" th:Object="${memberAccount}" enctype="multipart/form-data" autocomplete="off">
            <section class="form-input">
                <label>帳號/Email</label>
                <div class="input-area">
                    <div class="input-img"><img th:src="@{/images/person.png}"></div>
                    <input type="text" th:field="*{username}" placeholder="請輸入您的Email"/>
                </div>
            </section>
            <section class="form-input">
                <label>密碼</label>
                <div class="input-area">
                    <div class="input-img"><img th:src="@{/images/lock.png}"></div>
                    <input type="password" th:field="*{password}" maxlength="16" placeholder="請輸入您的密碼"/>
                </div>
            </section>
            <button>登入</button>
            <span>還不是會員嗎?<a th:href="@{/register}">立即加入</a></span>
        </form>
    </main>

    <script th:src="@{/js/login.js}"></script>
</body>
</html>

Controller 響應頁面

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.example.demo.entity.MemberAccount;
import com.example.demo.vo.MemberAccountVO;

@Controller
public class MemberAccountController {

	@RequestMapping(value = {"/", "/login"}, method = RequestMethod.GET)
	public String login(@ModelAttribute MemberAccount memberAccount) {
		
		return "login";
	}
	
}

Github

新增Thymeleaf 依賴及其配置
新增所需HTML 檔案及相關靜態資源與功能配置

參考網站

Thymeleaf標準方言


上一篇
Day 13 - Spring Boot & JPA
下一篇
Day 15 - Spring Boot 註冊與登入
系列文
誤打誤撞學了Spring Boot 還當了後端工程師30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言