thymeleaf常用语法

一、概述

thymeleaf是服务器端模板引擎,能够处理HTML、XML、JavaScript、CSS、文本等。thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。
thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。

thymeleaf官网
thymeleaf官网使用手册

二、thymeleaf工程配置

1.spring配置

<dependency> 
     <groupId>org.springframework.bootgroupId> 
     <artifactId>spring-boot-starter-thymeleafartifactId> 
dependency> 

2.thymeleaf使用详细配置

#配置到properties文件中 
#thymeleaf start 
#spring.thymeleaf.mode的默认值是HTML5,其实是一个很严格的检查,改为LEGACYHTML5可以得到一个可能更友好亲切的格式要求 
spring.thymeleaf.mode=LEGACYHTML5 
spring.thymeleaf.encoding=UTF-8 
spring.thymeleaf.content-type=text/html 
#开发时关闭缓存,不然没法看到实时页面 
spring.thymeleaf.cache=false 
#thymeleaf end 

注:LEGACYHTML5需要搭配一个额外的库NekoHTML才可用,需在pom.xml文件中添加该依赖,如下:
net.sourceforge.nekohtml nekohtml 1.9.22

三、thymeleaf 示例

@Controller 
public class HelloWorldController { 
   private static final Logger log = LoggerFactory.getLogger(HelloController.class); 

   @GetMapping(value = "/helloworld") 
   public String hello(Model model) { 
       String name = "thymeleaf"; 
       model.addAttribute("name", name); 
       return "helloworld"; 
   } 
} 

helloworld.html

 
<html xmlns:th="http://www.thymeleaf.org"> 
<head> 
   <title>hellotitle> 
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
head> 
<body> 
    
   <p th:text="${name} + ',HelloWorld,Welcome!'">静态页面文本显示p> 
body> 
html> 

## 四、基础语法
1.使html支持thymeleaf

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

2.获取变量值${}

 <p th:text="${name} + ',HelloWorld,Welcome!'">静态页面文本显示p> 

3.选择变量表达式*{…}

<div th:object="${session.user}"> 
    <p>Name: <span th:text="*{firstName}">Sebastianspan>.p> 
    <p>Surname: <span th:text="*{lastName}">Pepperspan>.p> 
    <p>Nationality: Saturnspan>.p> 
div> 
 
<div> 
    <p>Name: <span th:text="${session.user.firstName}">Sebastianspan>.p> 
    <p>Surname: <span th:text="${session.user.lastName}">Pepperspan>.p> 
    <p>Nationality: <span th:text="${session.user.nationality}">Saturnspan>.p> 
div> 

里面的原有的值是为给前端开发时做展示用的,这样在无网络的情况下也能运行。即完全可以前端先写出页面,模拟数据展现效果,后端人员再拿此模板修改即可。

4.链接表达式: @{…}
用来配合link、src、href使用的语法,类似的标签有:th:href和th:src

 
<a href="userProfile.html" th:href="@{http://localhost:8080/demo/profile(userId=${user.id})}">viewa> 
 
<a href="userProfile.html" th:href="@{/demo/profile(userId=${user.id})}">viewa> 

5.消息表达式#{}
通常与th:text属性一起使用,指明声明了th:text标签的文本是#{}中的key多对应的value,而标签内的文本将不显示

 
 

welcome<p>

6.工具对象表达式 #maps
常用于日期、集合、数组对象的访问。这些工具对象就是java对象,可以访问对应java对象的方法来进行各种操作。

<div th:if="${#maps.size(studentVO.students[__${rowStat.index}__].score)!=0}"> 
<label>${score.key}:label><input type="text" th:value="${score.value}"> 
div> 

其他工具对象表达式还有:#dates、#calendars、#numbers、#strings、#objects、#bools、#arrays、#lists、#sets

工具对象参考官网手册

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


/*
 * Format calendar with the standard locale format
 * Also works with arrays, lists or sets
 */
${#calendars.format(cal)}
${#calendars.arrayFormat(calArray)}
${#calendars.listFormat(calList)}
${#calendars.setFormat(calSet)}

/*
 * Format calendar with the ISO8601 format
 * Also works with arrays, lists or sets
 */
${#calendars.formatISO(cal)}
${#calendars.arrayFormatISO(calArray)}
${#calendars.listFormatISO(calList)}
${#calendars.setFormatISO(calSet)}

/*
 * Format calendar with the specified pattern
 * Also works with arrays, lists or sets
 */
${#calendars.format(cal, 'dd/MMM/yyyy HH:mm')}
${#calendars.arrayFormat(calArray, 'dd/MMM/yyyy HH:mm')}
${#calendars.listFormat(calList, 'dd/MMM/yyyy HH:mm')}
${#calendars.setFormat(calSet, 'dd/MMM/yyyy HH:mm')}

/*
 * Obtain calendar properties
 * Also works with arrays, lists or sets
 */
${#calendars.day(date)}                // also arrayDay(...), listDay(...), etc.
${#calendars.month(date)}              // also arrayMonth(...), listMonth(...), etc.
${#calendars.monthName(date)}          // also arrayMonthName(...), listMonthName(...), etc.
${#calendars.monthNameShort(date)}     // also arrayMonthNameShort(...), listMonthNameShort(...), etc.
${#calendars.year(date)}               // also arrayYear(...), listYear(...), etc.
${#calendars.dayOfWeek(date)}          // also arrayDayOfWeek(...), listDayOfWeek(...), etc.
${#calendars.dayOfWeekName(date)}      // also arrayDayOfWeekName(...), listDayOfWeekName(...), etc.
${#calendars.dayOfWeekNameShort(date)} // also arrayDayOfWeekNameShort(...), listDayOfWeekNameShort(...), etc.
${#calendars.hour(date)}               // also arrayHour(...), listHour(...), etc.
${#calendars.minute(date)}             // also arrayMinute(...), listMinute(...), etc.
${#calendars.second(date)}             // also arraySecond(...), listSecond(...), etc.
${#calendars.millisecond(date)}        // also arrayMillisecond(...), listMillisecond(...), etc.

/*
 * Create calendar (java.util.Calendar) objects from its components
 */
${#calendars.create(year,month,day)}
${#calendars.create(year,month,day,hour,minute)}
${#calendars.create(year,month,day,hour,minute,second)}
${#calendars.create(year,month,day,hour,minute,second,millisecond)}

${#calendars.createForTimeZone(year,month,day,timeZone)}
${#calendars.createForTimeZone(year,month,day,hour,minute,timeZone)}
${#calendars.createForTimeZone(year,month,day,hour,minute,second,timeZone)}
${#calendars.createForTimeZone(year,month,day,hour,minute,second,millisecond,timeZone)}

/*
 * Create a calendar (java.util.Calendar) object for the current date and time
 */
${#calendars.createNow()}

${#calendars.createNowForTimeZone()}

/*
 * Create a calendar (java.util.Calendar) object for the current date (time set to 00:00)
 */
${#calendars.createToday()}

${#calendars.createTodayForTimeZone()}

/*
 * ==========================
 * Formatting integer numbers
 * ==========================
 */

/* 
 * Set minimum integer digits.
 * Also works with arrays, lists or sets
 */
${#numbers.formatInteger(num,3)}
${#numbers.arrayFormatInteger(numArray,3)}
${#numbers.listFormatInteger(numList,3)}
${#numbers.setFormatInteger(numSet,3)}


/* 
 * Set minimum integer digits and thousands separator: 
 * 'POINT', 'COMMA', 'WHITESPACE', 'NONE' or 'DEFAULT' (by locale).
 * Also works with arrays, lists or sets
 */
${#numbers.formatInteger(num,3,'POINT')}
${#numbers.arrayFormatInteger(numArray,3,'POINT')}
${#numbers.listFormatInteger(numList,3,'POINT')}
${#numbers.setFormatInteger(numSet,3,'POINT')}


/*
 * ==========================
 * Formatting decimal numbers
 * ==========================
 */

/*
 * Set minimum integer digits and (exact) decimal digits.
 * Also works with arrays, lists or sets
 */
${#numbers.formatDecimal(num,3,2)}
${#numbers.arrayFormatDecimal(numArray,3,2)}
${#numbers.listFormatDecimal(numList,3,2)}
${#numbers.setFormatDecimal(numSet,3,2)}

/*
 * Set minimum integer digits and (exact) decimal digits, and also decimal separator.
 * Also works with arrays, lists or sets
 */
${#numbers.formatDecimal(num,3,2,'COMMA')}
${#numbers.arrayFormatDecimal(numArray,3,2,'COMMA')}
${#numbers.listFormatDecimal(numList,3,2,'COMMA')}
${#numbers.setFormatDecimal(numSet,3,2,'COMMA')}

/*
 * Set minimum integer digits and (exact) decimal digits, and also thousands and 
 * decimal separator.
 * Also works with arrays, lists or sets
 */
${#numbers.formatDecimal(num,3,'POINT',2,'COMMA')}
${#numbers.arrayFormatDecimal(numArray,3,'POINT',2,'COMMA')}
${#numbers.listFormatDecimal(numList,3,'POINT',2,'COMMA')}
${#numbers.setFormatDecimal(numSet,3,'POINT',2,'COMMA')}



/*
 * ==========================
 * Utility methods
 * ==========================
 */

/*
 * Create a sequence (array) of integer numbers going
 * from x to y
 */
${#numbers.sequence(from,to)}
${#numbers.sequence(from,to,step)}

/*
 * Converts to array, trying to infer array component class.
 * Note that if resulting array is empty, or if the elements
 * of the target object are not all of the same class,
 * this method will return Object[].
 */
${#arrays.toArray(object)}

/*
 * Convert to arrays of the specified component class.
 */
${#arrays.toStringArray(object)}
${#arrays.toIntegerArray(object)}
${#arrays.toLongArray(object)}
${#arrays.toDoubleArray(object)}
${#arrays.toFloatArray(object)}
${#arrays.toBooleanArray(object)}

/*
 * Compute length
 */
${#arrays.length(array)}

/*
 * Check whether array is empty
 */
${#arrays.isEmpty(array)}

/*
 * Check if element or elements are contained in array
 */
${#arrays.contains(array, element)}
${#arrays.containsAll(array, elements)}

/*
 * Converts to list
 */
${#lists.toList(object)}

/*
 * Compute size
 */
${#lists.size(list)}

/*
 * Check whether list is empty
 */
${#lists.isEmpty(list)}

/*
 * Check if element or elements are contained in list
 */
${#lists.contains(list, element)}
${#lists.containsAll(list, elements)}

/*
 * Sort a copy of the given list. The members of the list must implement
 * comparable or you must define a comparator.
 */
${#lists.sort(list)}
${#lists.sort(list, comparator)}

/*
 * Converts to set
 */
${#sets.toSet(object)}

/*
 * Compute size
 */
${#sets.size(set)}

/*
 * Check whether set is empty
 */
${#sets.isEmpty(set)}

/*
 * Check if element or elements are contained in set
 */
${#sets.contains(set, element)}
${#sets.containsAll(set, elements)}

/*
 * Compute size
 */
${#maps.size(map)}

/*
 * Check whether map is empty
 */
${#maps.isEmpty(map)}

/*
 * Check if key/s or value/s are contained in maps
 */
${#maps.containsKey(map, key)}
${#maps.containsAllKeys(map, keys)}
${#maps.containsValue(map, value)}
${#maps.containsAllValues(map, value)}

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

7.文本替换

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

8.运算符

  • 数学运算
    二元操作:+, - , * , / , %
    一元操作: - (负)
  • 逻辑运算
    一元 : and or
    二元 : !,not
  • 比较运算(为避免转义尴尬,可以使用括号中的英文进行比较运算!)
    比较:> , < , >= , <= ( gt , lt , ge , le )
    等于:== , != ( eq , ne )
  • 条件运算
    If-then: (if) ? (then)
    If-then-else: (if) ? (then) : (else)
    (value) ?: (defaultvalue)

9.条件
th:if、th:unless(th:unless于th:if恰好相反,只有表达式中的条件不成立,才会显示其内容)、th:switch

Logina> 
 
Logina> 
<div th:switch="${user.role}"> 
  <p th:case="'admin'">User is an administratorp> 
  <p th:case="#{roles.manager}">User is a managerp> 
  <p th:case="*">User is some other thingp> 
div> 

10.循环th:each

语法:th:each=“obj,iterStat:${objList}”
迭代对象可以是java.util.List,java.util.Map,数组等;
iterStat称作状态变量,属性有:
index:当前迭代对象的index(从0开始计算)
count: 当前迭代对象的index(从1开始计算)
size:被迭代对象的大小
current:当前迭代变量
even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)
first:布尔值,当前循环是否是第一个
last:布尔值,当前循环是否是最后一个

<ol> 
<li>List循环: 
<table border="1"> 
      <tr> 
        <th>用户名th> 
        <th>邮箱th> 
        <th>管理员th> 
        <th>状态变量:indexth> 
        <th>状态变量:countth> 
        <th>状态变量:sizeth> 
        <th>状态变量:current.userNameth> 
        <th>状态变量:eventh> 
        <th>状态变量:oddth> 
        <th>状态变量:firstth> 
        <th>状态变量:lastth> 
      tr> 
      <tr  th:each="user,userStat : ${list}"> 
        <td th:text="${user.userName}">Onionstd> 
        <td th:text="${user.email}">[email protected]td> 
        <td th:text="${user.isAdmin}">yestd> 
        <th th:text="${userStat.index}">当前迭代对象的index(从0开始计算)th> 
        <th th:text="${userStat.count}"> 当前迭代对象的index(从1开始计算)th> 
        <th th:text="${userStat.size}">被迭代对象的大小th> 
        <th th:text="${userStat.current.userName}">当前迭代变量th> 
        <th th:text="${userStat.even}">状态变量:even****th> 
        <th th:text="${userStat.odd}">布尔值,当前循环是否是偶数/奇数(从0开始计算)th> 
        <th th:text="${userStat.first}">布尔值,当前循环是否是第一个th> 
        <th th:text="${userStat.last}">布尔值,当前循环是否是最后一个th> 
      tr> 
    table> 
li> 
<li>Map循环: 
<div th:each="mapS:${map}"> 
<div th:text="${mapS}">div> 
div> 
li> 
<li>数组循环: 
<div th:each="arrayS:${arrays}"> 
<div th:text="${arrayS}">div> 
div> 
li> 
ol> 

五、常用标签

  • th:action
    定义后台控制器路径,类似标签的action属性
<form id="login-form" th:action="@{/login}">...form> 
  • th:each
    对象遍历,功能类似jstl中的标签
public class StudentVO{ 
        private List<Student> students; 
} 
public class Student implements Serializable{ 
        private String firstName; 
        private String lastName; 
} 

@RequestMapping(value = "/addStudent", method = RequestMethod.POST) 
public String addStudent(@ModelAttribute(value = "studentVO") 
StudentVO studentVO,ModelMap model) {...} 
<form id="login-form" th:action="@{/addStudent}" th:object="${studentVO}" method="POST"> 
<div class="student" th:each="stus,rowStat:${studentVO.students}"> 
<input type="text" class="firstName" value="" th:field="*{students[__${rowStat.index}__].firstName}">input> 
<input type="text" class="lastName" value="" th:field="*{students[__${rowStat.index}__].lastName}">input> 
div> 
form> 
  • th:field
    常用于表单字段绑定。通常与th:object一起使用。 属性绑定、集合绑定
public class LoginBean implements Serializable{... 
    private String username; 
    private List<User> user; 
} 
public class User implements Serializable{... 
    private String username;; 
} 

@RequestMapping(value = "/login", method = RequestMethod.POST) 
public String login(@ModelAttribute(value = "loginBean") LoginBean loginBean,ModelMap model) {..} 
<form id="login-form" th:action="@{/login}" th:object="${loginBean}">... 
    <input type="text" value="" th:field="*{username}">input> 
    <input type="text" value="" th:field="*{user[0].username}">input> 
form> 
  • th:href
    定义超链接,类似标签的href 属性。value形式为@{/logout}
<a th:href="@{/logout}" class="signOut">a> 
  • th:id
    div id声明,类似html标签中的id属性
div>
  • th:if
    条件判断
<div th:if="${rowStat.index} == 0">... 该div显示 ...div> 
  • th:include
    见th:fragment,如下

  • th:replace
    见th:fragment,如下

  • th:fragment
    声明定义该属性的div为模板片段,常用与头文件、页尾文件的引入。常与th:include,th:replace一起使用

 
<div th: fragment=" copy" > 
© 2011 The Good Thymes Virtual Grocery 
div> 

 
<div th: include=" /templates/footer : : copy" >div> 
<div th: replace=" /templates/footer : : copy" >div> 
  • th:object
    用于表单数据对象绑定,将表单绑定到后台controller的一个JavaBean参数。常与th:field一起使用进行表单数据绑定
public class LoginBean implements Serializable{...} 
@RequestMapping(value = "/login", method = RequestMethod.POST) 
public String login(@ModelAttribute(value = "loginBean") LoginBean loginBean,ModelMap model) {...} 
<form id="login-form" th:action="@{/login}" th:object="${loginBean}">...form> 
  • th:src
    用于外部资源引入,类似于

                    
                    

你可能感兴趣的:(java,js,thymleaf)