[转]thymeleaf常用标签

史上最详 Thymeleaf 使用教程

thymeleaf常用标签

Thymeleaf的基本语法

1. th:checked ,th:selected标签

<input type="radio" value="M" name="gender" th:checked="${data.gender}=='M'"/><input type="radio" value="F" name="gender" th:checked="${data.gender}=='F'"/><option th:selected="${cookie[draftStatus]}?${cookie[draftStatus].getValue()}=='WSH':false">未审核</option>

2. 日期格式化,字符串截取

https://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#dates

<span th:text="${#calendars.format(customerInfoVO.gmtCreated,'yyyy-MM-dd HH mm')}"></span>
<span th:text="${#strings.substring(entity.contactTime,0,10)}"></span>
tempo 写法 <span>{{gmtCreate | date 'YYYY-MM-DD HH:mm'}} </span>
*
 * ======================================================================
 * See javadoc API for class org.thymeleaf.expression.Calendars
 * ======================================================================
 */

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

3. a 标签带参数

<a th:if="(${entity.draftStatus}=='审核不通过') or (${entity.draftStatus}=='已发布') " class="btn btn-info" th:href="@{getItemById?(id=${entity.id},draftStatus=${entity.draftStatus}) }">编辑</a>
th:href="@{/index/bannerList}" 加‘/’ url 取相对路径 (http://localhost:8081/bauna)

 

4.th:attr

th:attr="itemId='DQR'+${entity.id},'src'=${entity.itemImg}"

5.列表序号 从1开始

<th:block th:each="entity,itemStat : ${contactNotes.getContactNotes()}">
  <tr class="alignCenter entryOrderRow">
    <td th:text="${itemStat.count+((page.curPage-1)*page.pageSize)}"></td>
    <td th:text="${#calendars.format(entity.gmtCreate,'yyyy-MM-dd')}"></td>
  </tr>
</th:block>

6.判断条件 表达式

<span th:if="1==1"></span> thymeleaf
{% if changeAmountTimes == 0 %} tempo模板
1111
{% else %}
22222
{% endif %}

thymeleaf模板属性的用法(更新:增加了if, each, 取值用法介绍)

逻辑判断

有两种方式可以解决if else展示不同数据

  • th:if th:unless
  • th:switch th:case

下面来看一下例子

@GetMapping("/")
public String index(Model model) {
    model.addAttribute("flag1", true);
    model.addAttribute("flag2", null);
    return "index";
}
<div th:if="${flag1}">show this when flag1 is true.</div>
<div th:unless="${flag1}">show this when flag1 is false.</div>

<div th:switch="${flag2}">
  <div th:case="${true}">show this when flag2 is true.</div>
  <div th:case="${false}">show this when flag2 is false.</div>
  <div th:case="*">flag2 != true and flag2 != false</div>
</div>

其实 th:unless可以看成是else的意思

7. 三元表达式

<td th:text="${entity.contactTimeNext!=null?(#strings.substring(entity.contactTimeNext,0,10)):' '}"></td>

8.tempo 渲染

<tr data-template-for="userRoleOrgList">
  <td colspan="2">部门:<span>{{orgName}}</span></td>
  <td colspan="10">角色:<span>{{roleDescription}}</span></td>
</tr>
userRoleOrgList为user 对象属性时 循环userRoleOrgList

9.字符串处理

${#strings.length(entity.content)} 获取字符串长度
${#strings.substring(entity.content,0,20)} 截取

How to split string in Thymeleaf

${#strings.arraySplit(yourVar, ':')}

<tbody id="portfolio" class="clear fix">
  <tr th:each="brickset : ${bricksets}" th:alt="${brickset.description}">
    <td>
      <div th:unless="${brickset.imageNames == null}">
        <div th:each="image,status : ${#strings.arraySplit(brickset.imageNames, '|')}">
          <a href="#" th:href="${imageBaseUrl + image}" th:remove="${image} == null ? tag" th:title="${brickset.brand.name}">
            <img src="#" th:src="${imageBaseUrl + image}" height="64" th:remove="${status.index} > 0 ? tag"/>
          </a>
        </div>
      </div>
    </td>
  </tr>
</tbody>

10.页面数据供js 调用

<script th:inline="javascript">
/*<![CDATA[*/
var goodsList = [[${goodsList}]];
/*]]>*/
</script>

11.th:class, th:classappend, th:colspan

<tr th:classappend="(${entity.isContact}=='Y')?a:b" class="row-body alignCenter">
如果${entity.isContact}=='Y' tr 采用样式a , 否则 用样式 b
<td th:colspan="${orderEntity.invoiceStatus}!=null?2:3"></td>

12.转义标签 th:utext

<span style="color:#41a1d2;" >2016-06-17 16:43</span>
tempo 转义 :Tempo.prepare('orderTempo',{'escape': false})

13.工具类

日期处理
${#dates.format(date,'dd/MMM/yyyy HH:mm')} ${#calendars.format(cal,'dd/MMM/yyyy HH:mm')}
数字
${#numbers.formatInteger(1000000,3,'COMMA')}
字符串
${#strings.contains(name,'EZ')} $(#strings.substring(name,3,5))
集合
${#arrays.length(array)} ${#lists.size(list)}

字典
${#maps.size(map)}

Thymeleaf对象的使用:数字对象

formatInteger(number,digits)
<div th:text="${#numbers.formatInteger(10,0)}"></div>
<div th:text="${#numbers.formatInteger(10.6,2)}"></div>
<div th:text="${#numbers.formatInteger(10.6,5)}"></div>
<div th:text="${#numbers.formatInteger(10.50,0)}"></div>
<div th:text="${#numbers.formatInteger(10.51,2)}"></div>
<div th:text="${#numbers.formatInteger(10000000,0,'COMMA')}"></div>
<div th:text="${#numbers.formatInteger(10000000,0,'POINT')}"></div>

arrayFormatInteger(numbers,digits)
<div th:each="num : ${#numbers.arrayFormatInteger(arr,0)}">
    <div th:text="${num}"></div>
</div>
listFormatInteger(numbers,digits)
<div th:each="num : ${#numbers.listFormatInteger(list,2)}">
    <div th:text="${num}"></div>
</div>
setFormatInteger(numbers,digits)
<div th:each="num : ${#numbers.setFormatInteger(set,4)}">
    <div th:text="${num}"></div>
</div>
formatInteger(number,digits)
11
10
10,000,000
10.000.000
arrayFormatInteger(numbers,digits)
11
listFormatInteger(numbers,digits)
11
setFormatInteger(numbers,digits)
0011

Themeleaf-#numbers.formatDecimal()使页面数据显示多位小数

全参方法:
numbers.formatDecimal(num,5,'COMMA',2,'POINT'):
num:表示要展示的数据
5:小数点前不满5位时用0补满5位
'COMMA':是用逗号表示千分位符
2:小数点后保留2位
”POINT“:使用”.“表示小数点

例子:
1.numbers.formatDecimal(10,0,2):10.00
2.numbers.formatDecimal(10,3,2):010.00
3.numbers.formatDecimal(10,5,'COMMA',2):00,010.00
4.numbers.formatDecimal(10,3,2,'COMMA'):010,00
5.numbers.formatDecimal(10,5,'COMMA',2,'POINT'):00,010.00

 

th:each遍历

java代码

List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        
Map<String, Object> m = new HashMap<String, Object>();
m.put("name", "name1");
m.put("age", "1");
list.add(m);
 
m = new HashMap<String, Object>();
m.put("name", "name2");
m.put("age", "2");
list.add(m);
 
m = new HashMap<String, Object>();
m.put("name", "name3");
m.put("age", "3");
list.add(m);
 
m = new HashMap<String, Object>();
m.put("name", "name4");
m.put("age", "4");
list.add(m);
 
m = new HashMap<String, Object>();
m.put("name", "name5");
m.put("age", "5");
list.add(m);
model.addAttribute("list", list);

接着看html写法:

简单遍历:
<table border="1">
    <tr th:each="m : ${list}"><!-- 其中m是个临时变量,像for(User u : userList)那样中的u-->
        <td th:text="${m.name}"/>
        <td th:text="${m.age}"/>
    </tr>
</table>

除了遍历,我们还可以拿到遍历的其他信息,比如下标,单行双行,这时要有一状态变量,假设命名为:iterStat,那么从iterStat中可获取的信息如下:
// 来自官网:

  • 当前迭代索引,从0开始。这是index属性。
  • 当前迭代索引,从1开始。这是count属性。
  • 迭代变量中的元素总数。这是size属性。
  • 每个迭代的iter变量。这是current属性。
  • 目前的迭代是偶数还是奇数。这些是even/odd布尔属性。
  • 目前的迭代是否是第一个。这是first布尔属性。
  • 目前的迭代是否是最后一个。这是last布尔属性。
<table border="1">
    <tr th:each="m,iterStat : ${list}">
        <td th:text="|下标:${iterStat.index} 下标是不是单数:${iterStat.odd}|"/>
        <td th:text="${m.name}"/>
        <td th:text="${m.age}"/>
    </tr>
</table>

thymleaf获取url里面的参数

有时候需要获取url里面传递的参数,应该使用以下方法:

http://localhost/login?sign=123456
${param.sign}

thymeleaf:字符串Strings常见的使用方法

Thymeleaf utility methods for Strings

判断是不是为空:null:
<span th:if="${name} != null">不为空</span>
<span th:if="${name1} == null">为空</span>
判断是不是为空字符串: "" <span th:if="${#strings.isEmpty(name1)}">空的</span>
判断是否相同:
<span th:if="${name} eq 'jack'">相同于jack,</span> <span th:if="${name} eq 'ywj'">相同于ywj,</span> <span th:if="${name} ne 'jack'">不相同于jack,</span>
不存在设置默认值:
<span th:text="${name2} ?: '默认值'"></span>
是否包含(分大小写):
<span th:if="${#strings.contains(name,'ez')}">包ez</span> <span th:if="${#strings.contains(name,'y')}">包j</span>
是否包含(不分大小写)
<span th:if="${#strings.containsIgnoreCase(name,'y')}">包j</span>
同理。。。下面的和JAVA的String基本一样。。。。不笔记解释,官网有 ${#strings.startsWith(name,'o')} ${#strings.endsWith(name, 'o')} ${#strings.indexOf(name,frag)}// 下标 ${#strings.substring(name,3,5)}// 截取 ${#strings.substringAfter(name,prefix)}// 从 prefix之后的一位开始截取到最后,比如 (ywj,y) = wj, 如果是(abccdefg,c) = cdefg//里面有2个c,取的是第一个c ${#strings.substringBefore(name,suffix)}// 同上,不过是往前截取 ${#strings.replace(name,'las','ler')}// 替换 ${#strings.prepend(str,prefix)}// 拼字字符串在str前面 ${#strings.append(str,suffix)}// 和上面相反,接在后面 ${#strings.toUpperCase(name)} ${#strings.toLowerCase(name)} ${#strings.trim(str)} ${#strings.length(str)} ${#strings.abbreviate(str,10)}// 我的理解是 str截取0-10位,后面的全部用…这个点代替,注意,最小是3位

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

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

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

Thymleaf中th:each标签遍历list如何获取index

简单介绍:传递给后台一个String类型的list,需要获取到list的每一个元素,然后进行筛选,得到正确的文本值,看代码就明白了

代码:

//后台java代码
//failList是一个String类型的list,存放的是状态码00 01 02 03 04 05 06中的某几种
map.addAttribute("failMsgList", failMsgList);
return VIEW_PATH + "/failDetail";//跳转到失败详情页面 
//html代码
<tr th:each="plan : ${planList}" th:id="${plan.planId}" th:attr="data-plan-status=${plan.planStatus}">
    <td th:text="${plan.planName}"></td>
    <td th:text="${plan.planCode}"></td>
<div th:switch="${failMsgList.get(__${planStat.index}__)}">
    <td th:case="00">后台系统故障</td>
    <td th:case="02">此方案待审核,不支持下架</td>
    <td th:case="01">此方案未上架,不支持下架</td>
    <td th:case="04">此方案未上架,不支持下架</td>
    <td th:case="03">此方案未上架,不支持下架</td>
    <td th:case="06">此方案已经下架</td>
    <td th:case="*"></td>
</div>
说明:failList里的状态码的获取,通过tr循环到第几行的索引来取

干货:

<tr th:each="user,userStat:${users}"> 

userStat是状态变量,如果没有显示设置状态变量,thymeleaf会默 认给个“变量名+Stat"的状态变量。

对arrayList对象users遍历,使用user作为接受参数接收,使用userStat作为users下标值,通过userStat.index得到当前所处下标值;

状态变量有以下几个属性:

  • index:当前迭代对象的index(从0开始计算)
  • count: 当前迭代对象的index(从1开始计算)
  • size:被迭代对象的大小
  • current:当前迭代变量
  • even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算)
  • first:布尔值,当前循环是否是第一个
  • last:布尔值,当前循环是否是最后一个
    当然,user和userStat可以自己定义名字,如果没定义状态变量,那么thymleaf会自动给一个“变量名+Stat”。

thymeleaf模板 只有length如何循环生成标签?

<span th:each="i,stat:${#numbers.sequence(10, 20)}">
     <span th:if="${(stat.count-1)%3==0}" th:text="${'啊' + i}"></span></br>
</span>

Thymeleaf语法取map值的方法

${map.get('key')}

 常见标签:

 

 

简写语法,转义,不转义

如果需要简写语法,可以使用以下命令:

不转议的简写语法是,括号

[(${variable})] 

转义的简写语法是,括号

[[${variable}]]

让我头都大了的双循环例子:

 

 1 <!-- 新增 -->
 2 <div class="skill-table">
 3     <th:block th:with="size=${#maps.size(OSs)}, lineCnt=${(size-1)/5}">
 4         <div class="skill-row" th:each="row, rowStat : ${#numbers.sequence(0, lineCnt)}">
 5             <th:block th:each="col, colStat : ${#numbers.sequence(1, 5)}"
 6                       th:with="mapKey=${row * 5 + col}">
 7                 <th:block th:if="${mapKey <= size}">
 8                     <div class="skill-item-name"
 9                          th:style="${(row == lineCnt) ? 'border-bottom: none' : ''}"
10                          th:text="${OSs.get(mapKey)}">
11                         , OS: [(${OSs.get(mapKey)})]
12                         , mapKey: [(${mapKey})]
13                         , size: [(${size})]
14                         , lineCnt: [(${lineCnt})]
15                         , col: [(${col})]
16                         , row: [(${row})]
17                     </div>
18                     <div class="skill-item-select"
19                          th:with="bottom=${row + '' == lineCnt + '' ? 'border-bottom: none;' : '' }, right=${col == 5 ? 'border-right: none' : ''}"
20                          th:style="${bottom + right}">
21                         <select name="IT_OS">
22                             <option value="0" selected="selected"> </option>
23                             <option value="1"></option>
24                             <option value="2"></option>
25                             <option value="3"></option>
26                         </select>
27                     </div>
28                 </th:block>
29             </th:block>
30         </div>
31     </th:block>
32 </div>
33 <!-- 修改 -->
34 <div class="skill-table">
35     <div class="skill-row">
36         <div class="skill-name">OS</div>
37         <div class="skill-meisai">
38             <div class="skill-table" th:with="IT_OSs=${#strings.arraySplit(MODEL.IT_OS, ',')}">
39                 <th:block th:with="size=${#maps.size(OSs)}, lineCnt=${(size-1)/5}, arrayLength=${#arrays.length(IT_OSs)}">
40                     <div class="skill-row" th:each="row, rowStat : ${#numbers.sequence(0, lineCnt)}">
41                         <th:block th:each="col, colStat : ${#numbers.sequence(1, 5)}"
42                                   th:with="mapKey=${row * 5 + col}">
43                             <th:block th:if="${mapKey <= size}"
44                                       th:with="arrayIndex=${row * 5 + col -1}">
45                                 <div class="skill-item-name"
46                                      th:style="${(row == lineCnt) ? 'border-bottom: none' : ''}"
47                                      th:text="${OSs.get(mapKey)}">
48                                     , OS: [(${OSs.get(mapKey)})]
49                                     , index: [(${colStat.index})]
50                                     , count: [(${colStat.count})]
51                                     , mapKey: [(${mapKey})]
52                                     , arrayLength: [(${arrayLength})]
53                                     , arrayIndex: [(${arrayIndex})]
54                                     , size: [(${size})]
55                                     , lineCnt: [(${lineCnt})]
56                                     , col: [(${col})]
57                                     , row: [(${row})]
58                                 </div>
59                                 <div class="skill-item-select"
60                                      th:if="${arrayIndex < arrayLength}"
61                                      th:with="bottom=${row + '' == lineCnt + '' ? 'border-bottom: none;' : '' }, right=${col == 5 ? 'border-right: none' : ''}, IT_OS=${IT_OSs[arrayIndex]}"
62                                      th:style="${bottom + right}">
63                                     <select name="IT_OS" th:disabled="${@PERMISSION_CONTEXT.hasRole('C','D')}"
64                                             th:with="VALUEs=${#strings.arraySplit(IT_OS, '-')}">
65                                         <option value="0" th:selected="${VALUEs[1]} eq '0'"> 
66                                         </option>
67                                         <option value="1" th:selected="${VALUEs[1]} eq '1'">68                                         </option>
69                                         <option value="2" th:selected="${VALUEs[1]} eq '2'">70                                         </option>
71                                         <option value="3" th:selected="${VALUEs[1]} eq '3'">72                                         </option>
73                                     </select>
74                                 </div>
75                                 <div class="skill-item-select"
76                                      th:unless="${arrayIndex < arrayLength}"
77                                      th:with="bottom=${row + '' == lineCnt + '' ? 'border-bottom: none;' : '' }, right=${col == 5 ? 'border-right: none' : ''}"
78                                      th:style="${bottom + right}">
79                                     <select name="IT_OS" th:disabled="${@PERMISSION_CONTEXT.hasRole('C','D')}">
80                                         <option value="0" selected="selected"> </option>
81                                         <option value="1"></option>
82                                         <option value="2"></option>
83                                         <option value="3"></option>
84                                     </select>
85                                 </div>
86                             </th:block>
87                         </th:block>
88                     </div>
89                 </th:block>
90             </div>
91         </div>
92     </div>
93 </div>
双循环

 

 

 

posted @ 2020-03-04 19:39  —八戒—  阅读(1503)  评论(0编辑  收藏  举报