The most detailed Thymeleaf usage tutorial ever

Preface

Before proceeding, I suggest referring to another of my blogs: Play SpringBoot 2 Fast Integration | Thymeleaf See how to use Thymeleaf in SpringBoot.It is also important to note that the namespace of Thymeleaf needs to be declared on the html in the template page, as follows:

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

Now you can start the Thymeleaf tutorial!

Thymeleaf is described in full text based on Thymeleaf version 3.0.11.RELEASE.

Basic Grammar

Text label th:text/th:utext

Display operation for text content.

  1. th:text text text replacement does not resolve html
  2. Th:utextText replacement resolves html

Code demonstration:

    @RequestMapping("/th")
    public String th(Model model){
        String msg = "<h1>I am h1</h1>";
        model.addAttribute("msg",msg);
        return "/course/th";
    }

th:text text text replacement does not resolve html

<p th:text="text Label:  + ${msg}"></p>

Result page:

<p>text Label:<h1>I am h1</h1></p>

Effects of Visitor Access:

Th:utextText replacement resolves html

<p th:utext="utext Label: + ${msg}"></p>

The effect of the tour is as follows:

The effect of using + is the same as using |, as shown in the following code:

<p th:utext="utext Label: + ${msg}"></p>
<p th:utext="|utext Label: ${msg}|"></p>

StringBuilder

Stitching strings are stitched by + or |

Code demonstration:

    @RequestMapping("/th")
    public String th(Model model){
        model.addAttribute("a",1);
        model.addAttribute("b",2);
        return "/course/th";
    }

Template page:

<p th:text="${a}+${b}"></p>

Result page:

<p>3</p>

Template page:

<p th:text="|${a} ${b}|"></p>

Result page:

<p>1 2</p>

Template page:

<p th:text="${a} > ${b}"></p>

The result is:

<p>false</p> 

java code:

    @RequestMapping("/th")
    public String th(Model model){
        model.addAttribute("flag",true);
        return "/course/th";
    }

Template page:

<p th:text="!${flag}"></p>

Result page:

<p>false</p>

{...} and ${...} expressions
Normally {...} is the same as ${...}, but *{...} is generally used with th:object to simplify object properties.

Code demonstration:

    @RequestMapping("/th")
    public String th(Model model){
        User user = new User("ljk",18);
        model.addAttribute("user",user);
        return "/course/th";
    }

Use ${...} operation
Template code:

<p th:text="${user.name}"></p>
<p th:text="${user.age}"></p>

Result page:

<p>ljk</p><p>18</p>

**Use *{...} Operation**
Template code:

<p th:text="*{user.name}"></p>
<p th:text="*{user.age}"></p>

Result page:

<p>ljk</p><p>18</p>

** Use *{...} unique operations**
Template code:

<div th:object="${user}" >
    <p th:text="*{name}"></p>
    <p th:text="*{age}"></p>
</div>

Result page:

<p>ljk</p><p>18</p>

#{...} expression

Used for international message.properties property reading
Define message.properties configuration file

Define internationalization processing transformation processing classes

@Configuration
public class LocaleResolverConfig {
    @Bean(name="localeResolver")
    public LocaleResolver localeResolverBean() {
        return new SessionLocaleResolver();
    }
}

Define controller for Internationalization

@Controller
public class ProductController {
    
    @Autowired
    private LocaleResolver localeResolver;
    private  ProductService productService = new ProductService();
      
    @RequestMapping("/")
    public String useT(Model model,HttpServletRequest request,HttpServletResponse response) {
        //Set access to user information to session
        request.getSession(true).setAttribute("user", new User("At the table", "Bright moon", "CHINA", null));
        localeResolver.setLocale(request,response,Locale.CHINA);
        return "productList";
    }
}

If message_en_US.properties and message_zh_CN.properties are not defined, the information in message.properties is taken by default.
If Locale = Locale.CHINA, take message_zh_CN.properties
If Locale = Locale.US, take message_en_US.properties.

Template code:

<p th:utext="#{home.welcome(${session.user.name})}">Welcome to our grocery store, Sebastian!</p>

The effect of accessing the controller's path:

~{...} Fragment Expression

This is generally used in conjunction with the syntax of the template layout. See the following template layout tutorial for details.

@{...} Link URL expression

Typically used in conjunction with th:href and th:src to display URL links in Web applications.The @{...} expression Thymeleaf can help us stitch together the full paths accessed by web applications, and we can stitch together parameters through ()

Code demonstration:

Template code:

<img th:src="@{/images/gtvglogo.png}"  />

Result page:

<img src="/sbe/images/gtvglogo.png">

Template code:

<a th:href="@{/product/comments(prodId=${prod.id})}" >See</a>

Result page:

<a href="/sbe/product/comments?prodId=2">See</a>

Template code:

 <a  th:href="@{/product/comments(prodId=${prod.id},prodId2=${prod.id})}" >See</a>

Result page:

<a href="/sbe/product/comments?prodId=2&amp;prodId2=2">See</a>

Conditional judgment th:if/th:unless

th:if is displayed when the condition is true.
th:unless is displayed when the condition is false.

Code demonstration:

java code:

    @RequestMapping("/thif")
    public String thif(Model model){
        model.addAttribute("flag",true);
        return "/course/thif";
    }

Template page:

<p th:if="${flag}">if judge</p>

Result page:

<p>if judge</p>

Template page:

<p th:unless="!${flag}">unless judge</p>

Result page:

<p>unless judge</p>

switch

th:switch We can do similar conditional expressions with switch.
Code demonstration:
java code:

    @RequestMapping("/thswitch")
    public String thswitch(Model model){
        User user = new User("ljk",23);
        model.addAttribute("user",user);
        return "/course/thswitch";
    }

Template page:

<div th:switch="${user.name}">
      <p th:case="'ljk'">User is  ljk</p>
      <p th:case="ljk1">User is ljk1</p>
</div>

Result page:

<div><p> User is ljk</p></div>

for loop

Th:ach Traversal Collection

Code demonstration:
java code:

    @RequestMapping("/theach")
    public String theach(Model model){
        
        List<User> userList = new ArrayList<User>();
        User user1 = new User("ljk",18);
        User user2 = new User("ljk2",19);
        User user3 = new User("ljk3",20);
        User user4 = new User("lj4",21);
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);
        model.addAttribute("userList",userList);
        
        List<String> strList = new ArrayList<String>();
        strList.add("ljk");
        strList.add("ljk2");
        strList.add("ljk3");
        strList.add("lj4");
        model.addAttribute("strList",strList);
        
        return "/course/theach";
}

Template page:

     <table>
      <thead>
        <tr>
          <th>User Name</th>
          <th>User Age</th>
        </tr>
      </thead>
      <tbody>
        <tr th:each="user : ${userList}" th:class="${userStat.odd}? 'odd'">
          <td th:text="${user.name}">Onions</td>
          <td th:text="${user.age}">2.41</td>
        </tr>
      </tbody>
    </table>
----------------------------------------------------------------------
    <table>
      <thead>
        <tr>
          <th>User Name</th>
        </tr>
      </thead>
      <tbody>
        <tr th:each="str : ${strList}" th:class="${strStat.odd}? 'odd'">
          <td th:text="${str}">Onions</td>
        </tr>
      </tbody>
    </table>

Result page:

We can use the convenient variable name + Stat to get whether the index is first or last, etc.
A convenient variable name + Stat is called a state variable, and its properties are:

  • Index: Iterative index of the current iteration object, starting at 0, which is an index property;
  • count: The iteration index of the current iteration object, which is a statistical property starting from 1;
  • Size: The total number of iterated variable elements, which is the size property of the iterated object;
  • Current: current iteration variable;
  • Even/odd: Boolean value, whether the current cycle is even/odd (from 0);
  • First: Boolean value, is the current loop the first;
  • Last:Boolean value, is the current loop the last
  • The for loop introduction refers to the th:each iteration cycle of common attributes of the CSDN blogger liubin5620 Thymeleaf template engine: https://blog.csdn.net/liubin5620/article/details/80470619

th:href

Links used to declare the href attribute on the a tag This syntax is used with the @{.} expression.

Code demonstration:
java code:

    @RequestMapping("/thhref")
    public String thhref(Model model){
        return "/course/thhref";
    }

Template code:

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

Result page:

<a href="/sbe/">Return to Home Page</a>

th:class

Used to declare class attribute information on labels.

Code demonstration:
java code:

    @RequestMapping("/thclass")
    public String thclass(Model model){
        return "/course/thclass";
    }

Template page:

<p th:class=" 'even'? 'even' : 'odd'" th:text=" 'even'? 'even' : 'odd'"></p>

Result page:

<p class="even">even</p>

th:attr

Used to declare attribute information in html or custom.

Code demonstration:

java code:

@RequestMapping("/thattr")
public String thattr(Model model){
    return "/course/thattr";
}

Template page:

<img  th:attr="src=@{/images/gtvglogo.png}" />

Result page:

<img src="/sbe/images/gtvglogo.png">

th:value

Used to declare value attribute information in html.

Code demonstration:
java code:

@RequestMapping("/thvalue")
public String thvalue(Model model){
  model.addAttribute("name", "ljk");
  return "/course/thvalue";
}

Template page:

    <input type="text" th:value="${name}" />

Result page:

<input type="text" value="ljk">

th:action

Used to declare action attribute information in HTML front tags.

Code demonstration:
java code:

@RequestMapping("/thaction")
  public String thaction(Model model){
  return "/course/thaction";
}

Template page:

    <form action="subscribe.html" th:action="@{/subscribe}">
        <input type="text" name="name" value="abc"/>
    </form>

Result page:

<form action="/sbe/subscribe">
        <input type="text" name="name" value="abc">
    </form>

th:id

Used to declare htm id attribute information.

Code demonstration:
java code:

    @RequestMapping("/thid")
    public String thid(Model model){
        model.addAttribute("id", 123);
        return "/course/thid";
    }

Template page:

<p th:id="${id}"></p>

Result page:

<p id="123"></p>

th:inline

The syntax used for JavaScript inline operations, as described below

th:onclick

Used to declare onclick events in htm.

Code demonstration:
java code:

@RequestMapping("/thonclick")
public String honclick(Model model){
  return "/course/thonclick";
}

Template page:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
    function showUserInfo(){
        alert("i am zhuoqianmingyue!")
    }
</script>
</head>
<body>
   <p th:onclick="'showUserInfo()'">Click on me</p>
</body>
</html>

Result page:

<p onclick="showUserInfo()">Click on me</p>

th:selected

Used to declare selected attribute information in htm.

Code demonstration:
java code:

    @RequestMapping("/thselected")
    public String thselected(Model model){
        model.addAttribute("sex", 1);
        return "/course/thselected";
    }

Template page:

<select>
    <option name="sex"></option>
    <option th:selected="1 == ${sex}">male</option>
    <option th:selected="0 == ${sex}">female</option>
</select>

Result page:

<select>
<option name="sex"></option>
    <option selected="selected">male</option>
    <option>female</option>
</select>

th:src

Used to declare src attribute information in img in htm.

Code demonstration:
java code:

@RequestMapping("/thsrc")
public String thsrc(Model model){
    return "/course/thsrc";
}

Template page:

<img  title="GTVG logo" th:src="@{/images/gtvglogo.png}" />

Result page:

<img title="GTVG logo" src="/sbe/images/gtvglogo.png">

th:style

Style information used to declare label css in htm.

Code demonstration:
java code:

RequestMapping("/thstyle")
public String thstyle(Model model){
  model.addAttribute("isShow", true);
  return "/course/thstyle";
}

Template page:

<p th:style="'display:' + @{(${isShow} ? 'none' : 'block')} + ''"></p>

Result page:

<p style="display:none"></p>

th:with

Used for the use of local variable definitions in the thymeleaf template page.

Code demonstration:
java code:

    @RequestMapping("/thwith")
    public String thwith(Model model){
        model.addAttribute("today", new Date());
        return "/course/thwith";
    }

Template page:

<p th:with="df='dd/MMM/yyyy HH:mm'">
        Today is: <span th:text="${#dates.format(today,df)}">13 February 2011</span>
    </p>

Result page:

<span>02/June/2019 06:52</span>

java code:

    @RequestMapping("/thwith")
    public String thwith(Model model){
        List<User> users = new ArrayList<User>();
        users.add(new User("ljk",18));
        users.add(new User("ljk2",18));
        model.addAttribute("users",users);
        return "/course/thwith";
    }

Template page:

<div th:with="firstEle=${users[0]}">
    <p>
        //The first user's name is: <span th:text="${firstEle.name}"></span>.
    </p>
</div>

Result page:

<div>
          <p>
            //The first user's name is: <span>ljk</span>.
          </p>
</div>

Another usage is in reference fragments with parameters in the template layout as follows:

<div th:replace="::frag" th:with="onevar=${value1},twovar=${value2}">

Refer to the description in Template Layout for a specific demonstration.

Elvis operator

The Elvis operation can be interpreted as a simple trinary operation to determine whether it is null or not. If the value is nullzhe, the default value is displayed, and if it is not null, the original value is displayed.

Code demonstration:
java code:

    @RequestMapping("/elvis")
    public String elvis(Model model){
        model.addAttribute("age", null);
        return "/course/elvis";
    }

Template page:

 <p>Age: <span th:text="${age}?: 'Age is nll'"></span></p>

Result page:

<p>Age: <span>Age is nll</span></p>

java code:

@RequestMapping("/elvis")
public String elvis(Model model){
  model.addAttribute("age2", 18);
  return "/course/elvis";
}

Template page:

<p>Age2: <span th:text="${age2}?: 'Age is nll'"></span></p>

Result page:

<p>Age2: <span>18</span></p>

Ternary expression

Can we use a ternary expression in thymeleaf's syntax by passing it in th:x?1 option: 2 option.

Code demonstration:
java code:

    @RequestMapping("/threeElementOperation")
    public String threeElementOperation(Model model){
        return "/course/threeElementOperation";
    }

Template page:

<p th:class=" 'even'? 'even' : 'odd'" th:text=" 'even'? 'even' : 'odd'"></p>

Result page:

<p class="even">even</p>

java code:

    @RequestMapping("/threeElementOperation")
    public String threeElementOperation(Model model){
        model.addAttribute("name", "ljk");
        return "/course/threeElementOperation";
    }

Template page:

<p th:value="${name eq 'ljk' ? 'Handsome guy':'Ugly man'}" th:text="${name eq 'ljk' ? 'Handsome guy':'Ugly man'}"></p>

Result page:

 <p value="Handsome guy">Handsome guy</p>

Conditional expression action characters:
gt:great than
ge:great equal (greater than or equal)
eq:equal (equal)
lt:less than (less than)
le:less equal (less than or equal)
ne:not equal

No-Operation () Do nothing
A special abbreviation of the Elvis operator that does nothing when the value shown is null.

Code demonstration:
java code:

@RequestMapping("/noOperation")
public String noOperation(Model model){
    model.addAttribute("name", null);
    return "/course/noOperation";
}

Template page:

<span th:text="${name} ?: _">no user authenticated</span>

Result page:

<span>no user authenticated</span>

The following fixed-value Boolean attributes exist in standard dialects:

th:async th:autofocus th:autoplay
th:checked th:controls th:declare
th:default th:defer th:disabled
th:formnovalidate th:hidden th:ismap
th:loop th:multiple th:novalidate
th:nowrap th:open th:pubdate
th:readonly th:required th:reversed
th:scoped th:seamless th:selected

For specific HTML5 properties:

th:abbr th:accept th:accept-charset
th:accesskey th:action th:align
th:alt th:archive th:audio
th:autocomplete th:axis th:background
th:bgcolor th:border th:cellpadding
th:cellspacing th:challenge th:charset
th:cite th:class th:classid
th:codebase th:codetype th:cols
th:colspan th:compact th:content
th:contenteditable th:contextmenu th:data
th:datetime th:dir th:draggable
th:dropzone th:enctype th:for
th:form th:formaction th:formenctype
th:formmethod th:formtarget th:fragment
th:frame th:frameborder th:headers
th:height th:high th:href
th:hreflang th:hspace th:http-equiv
th:icon th:id th:inline
th:keytype th:kind th:label
th:lang th:list th:longdesc
th:low th:manifest th:marginheight
th:marginwidth th:max th:maxlength
th:media th:method th:min
th:name th:onabort th:onafterprint
th:onbeforeprint th:onbeforeunload th:onblur
th:oncanplay th:oncanplaythrough th:onchange
th:onclick th:oncontextmenu th:ondblclick
th:ondrag th:ondragend th:ondragenter
th:ondragleave th:ondragover th:ondragstart
th:ondrop th:ondurationchange th:onemptied
th:onended th:onerror th:onfocus
th:onformchange th:onforminput th:onhashchange
th:oninput th:oninvalid th:onkeydown
th:onkeypress th:onkeyup th:onload
th:onloadeddata th:onloadedmetadata th:onloadstart
th:onmessage th:onmousedown th:onmousemove
th:onmouseout th:onmouseover th:onmouseup
th:onmousewheel th:onoffline th:ononline
th:onpause th:onplay th:onplaying
th:onpopstate th:onprogress th:onratechange
th:onreadystatechange th:onredo th:onreset
th:onresize th:onscroll th:onseeked
th:onseeking th:onselect th:onshow
th:onstalled th:onstorage th:onsubmit
th:onsuspend th:ontimeupdate th:onundo
th:onunload th:onvolumechange th:onwaiting
th:optimum th:pattern th:placeholder
th:poster th:preload th:radiogroup
th:rel th:rev th:rows
th:rowspan th:rules th:sandbox
th:scheme th:scope th:scrolling
th:size th:sizes th:span
th:spellcheck th:src th:srclang
th:standby th:start th:step
th:style th:summary th:tabindex
th:target th:title th:type
th:usemap th:value th:valuetype
th:vspace th:width th:wrap
th:xmlbase th:xmllang th:xmlspace

inline

How to use inline operations

We can turn on inline operations by declaring th:inline="text" on the parent tag.Of course, if you want the entire page to be used, you can declare it directly on the body.The specific usage is shown in the code below.

Template page:

<div th:inline="text">
<p>Hello, [[${user.name}]]!</p>
</div>

The results are as follows:

<div>
<p>Hello,zhuoqianmingyue!</p>
</div>

Such an operation is equivalent to using th:text.

<div>
<p th:text="Hello,+${user.name}"></p>
</div>

[[[...]] corresponds to th:text, [(...)] corresponds to th:utext

Disable inline operations

This allows us to disable inline operations by declaring th:inline="none" on the parent tag or this tag, as shown in the following code:
Template page:

<p th:inline="none">A double array looks like this: [[1, 2, 3], [4, 5]]!</p>

Result page:

<p>A double array looks like this: [[1, 2, 3], [4, 5]]!</p>

JavaScript Inline

If we want to use inline operations in JavaScript, we need to declare th:inline="javascript" on the script tag and then we can use inline operations in the script tag.This is done in the following code:
Template page:

<script th:inline="javascript">
    var username = [[${user.name}]];
</script>

Result page:

<script th:inline="javascript">
    var username = "zhuoqianmingyue";
</script>

CSS Inline

We can turn on the use of inline in CSS by declaring th:inline="css" on the style tag as follows:

<style th:inline="css">
  ...
</style>

For example, suppose we set two variables to two different String values:
classname = 'main elems'
align = 'center'
We can use them as follows:

<style th:inline="css">
    .[[${classname}]] {
      text-align: [[${align}]];
    }
</style>

Result page:

<style th:inline="css">
    .main\ elems {
      text-align: center;
    }
</style>

Template Layout

Define Reference Fragment Code

SpringBoot 2.0 requires thymeleaf-layout-dialect dependency to be introduced first when using template layout

<dependency>
    <groupId>nz.net.ultraq.thymeleaf</groupId>
    <artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>

Define footer.html page This page is our reference snippet code

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div th:fragment="copy">
        &copy; 2011 The Good Thymes Virtual Grocery
    </div>
</body>
</html>

We can use th:fragment s to define reference fragments, which can then be referenced on other pages.

Define reference page index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <div th:insert="~{footer :: copy}"></div>
</body>
</html>

Introducing fragments defined in footer.html using th:insert and ~{...} fragment reference expressions

Define a controller to access the index page

@Controller
@RequestMapping("/layout")
public class LayOutController {
    @RequestMapping("/index")
    public String index(){
        return "/layout/index";
    }
}

Testing
http://localhost:8090/sbe/layout/index

Result page:

<div>
  <div>
      © 2011 The Good Thymes Virtual Grocery
  </div>
</div>

The code below is written in the same way.If you find ~{footer:: copy} more difficult to write, you can use the abbreviated form footer:: copy.

<div th:insert="footer :: copy"></div>
<div th:insert="~{footer :: copy}"></div>

Declare fragments by id attribute

We can define a reference fragment by th:fragment, but we can also make a reference to a fragment by declaring the id attribute on the reference fragment code as follows:

Define reference fragment code template page footer.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="copy-section" >
    &copy; 2011 The Good Thymes Virtual Grocery
</div>
</body>
</html>

Template page referencing reference fragments: index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div th:insert="~{footer :: #copy-section}"></div>
</body>
</html>

Result page:

<div>
<div id="copy-section">
    © 2011 The Good Thymes Virtual Grocery
</div>
</div>

footer :: #copy-section and~{footer :: #copy-section} results are consistent.

The difference between th:insert and th:replace (and th:include)

  • Th:insert is the simplest: it will display both the label using th:insert and the content of the reference fragment
  • th:replace Inserts the label and content of the reference fragment
  • th:include is similar to th:insert, inserting only the contents of this fragment.

th:insert
java code:

@Controller
@RequestMapping("/layout")
public class LayoutController {
    @RequestMapping("/index2")
    public String index2(Model model) {
        return "/layout/index2";
    }
}

Declare Reference Fragment Template Page: footer2.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<footer th:fragment="copy">
  &copy; 2011 The Good Thymes Virtual Grocery
</footer>
</body>
</html>

Reference Fragment Template Page: index2.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:insert="footer2 :: copy"></div>
<div th:replace="footer2 :: copy"></div>
<div th:include="footer2:: copy"></div>
</body>
</html>

th:insert result:

<div>
<footer>
  © 2011 The Good Thymes Virtual Grocery
</footer>
</div>

th:replace result:

<footer>
  © 2011 The Good Thymes Virtual Grocery
</footer>

th:include result:

<div>
  © 2011 The Good Thymes Virtual Grocery
</div>

Reference fragment with parameters

Define reference fragment code template page footer.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div th:fragment="frag (onevar,twovar)">
    <p th:text="${onevar} + ' - ' + ${twovar}">...</p>
</div>
</body>
</html>

Template page referencing reference fragments: index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <div th:insert="footer :: frag('a','b')"></div>
</body>
</html>

Result page:

<div>
<div>
    <p>a - b</p>
</div>
</div>

Th:insert="footer:: frag (onevar='a', twovar='b')" and th:insert="footer:: frag('a','b') have the same effect.Another way to write it is to use th with:
th:insert="::frag" th:with="onevar='a',twovar='b'"

Delete Template Fragments

We need to add some simulation data for the convenience of viewing the following page productList.html directly (mainly as a prototype page).

<table>
  <tr>
    <th>NAME</th>
    <th>PRICE</th>
    <th>IN STOCK</th>
    <th>COMMENTS</th>
  </tr>
  <tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'">
    <td th:text="${prod.name}">Onions</td>
    <td th:text="${prod.price}">2.41</td>
    <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
    <td>
      <span th:text="${#lists.size(prod.comments)}">2</span> comment/s
      <a href="comments.html" 
         th:href="@{/product/comments(prodId=${prod.id})}" 
         th:unless="${#lists.isEmpty(prod.comments)}">view</a>
    </td>
  </tr>
  <tr class="odd">
    <td>Blue Lettuce</td>
    <td>9.55</td>
    <td>no</td>
    <td>
      <span>0</span> comment/s
    </td>
  </tr>
  <tr>
    <td>Mild Cinnamon</td>
    <td>1.99</td>
    <td>yes</td>
    <td>
      <span>3</span> comment/s
      <a href="comments.html">view</a>
    </td>
  </tr>
</table>

The code above simulates the data, but the following simulated data is displayed when we access the page through a normal controller.

 <tr class="odd">
    <td>Blue Lettuce</td>
    <td>9.55</td>
    <td>no</td>
    <td>
      <span>0</span> comment/s
    </td>
  </tr>
  <tr>
    <td>Mild Cinnamon</td>
    <td>1.99</td>
    <td>yes</td>
    <td>
      <span>3</span> comment/s
      <a href="comments.html">view</a>
    </td>
  </tr>

Let's look directly at the page as follows:

View the effect of the page through url access:

thymeleaf gives us th:remove to help us solve this problem:

 <tr class="odd" th:remove="all">
    <td>Blue Lettuce</td>
    <td>9.55</td>
    <td>no</td>
    <td>
      <span>0</span> comment/s
    </td>
  </tr>
  <tr th:remove="all">
    <td>Mild Cinnamon</td>
    <td>1.99</td>
    <td>yes</td>
    <td>
      <span>3</span> comment/s
      <a href="comments.html">view</a>
    </td>
  </tr>
  

We declare th:remove="all" on the simulation data and then access it via url without our previous simulation data

View the page directly or you can see our simulated data.

What does this value in the all attribute mean?th:remove can be represented in five different ways depending on its value:

  • All: Delete the containing tag and all its child tags.
  • body: Do not delete the containing tag, but delete all its child tags.
  • Tag: Delete the containing tag without deleting its children.
  • all-but-first: Delete all but the first child items that contain tags.
  • none: Nothing to do.This value is useful for dynamic evaluation.

    When we know what it means to have no attributes, we can use the

    Declare it once instead of defining multiple th:remove="all"

    Predefined Tool Objects

    #dates

    Processing date data generation, conversion, getting the specific number of days and years of the date.

    Code demonstration:

    java code:

        @RequestMapping("/dates")
        public String dates(Model model) throws ParseException{
            Date date = new Date();
            model.addAttribute("date",date);
            
            String dateStr = "2018-05-30";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date2 =  sdf.parse(dateStr); 
            Date[] datesArray = new Date[2];
            datesArray[0] = date;
            datesArray[1] = date2;
            model.addAttribute("datesArray",datesArray);
            
            List<Date> datesList = new ArrayList<Date>();
            datesList.add(date);
            datesList.add(date2);
            model.addAttribute("datesList",datesList);
            return "/course/dates";
        }

    format operation

    java code:

    Date date = new Date();

    Template page:

    <span th:text="${#dates.format(date)}">4564546</span>

    Result page:

    <span>May 30, 2019, 10:03:24 seconds</span>

    java code:

    Date date = new Date();

    Template page:

    <span th:text="${#dates.format(date, 'dd/MMM/yyyy HH:mm')}">4564546</span>

    Result page:

    <span>30/May/2019 10:03 </span>

    java code:

    Date[] datesArray = new Date[2];
            datesArray[0] = date;
            datesArray[1] = date2;

    Template page:

    <p th:text="${#dates.format(datesArray, 'yyyy-MM-dd HH:mm')}"></p>

    Result page:

    <p>2019-05-30 10:03</p>

    I don't know why this is just a date data fetch

    java code:

    List<Date> datesList = new ArrayList<Date>();
            datesList.add(date);
            datesList.add(date2);
            model.addAttribute("datesList",datesList);

    Template page:

    <p th:text="${#dates.listFormat(datesList, 'dd/MMM/yyyy HH:mm')}"></p>

    Result page:

    <p> [30/May/2019 10:03, 30/May/2018 00:00]</p>

    Get Date Attribute Operation
    java code:

    Date date = new Date();

    Template page:

    <p th:text="${#dates.day(date)} "></p>

    Result page:

    <p>30</p>

    java code:

    Date date = new Date();

    Template page:

    <p th:text="${#dates.month(date)}"></p>

    Result page:

    <p>5</p>

    java code:

    Date date = new Date();

    Template page:

    <p th:text="${#dates.monthName(date)}"></p>

    Result page:

    <p>May</p>

    java code:

    Date date = new Date();

    Template page:

    <p th:text="${#dates.monthNameShort(date)} "></p>     

    Result page:

    <p>May</p>

    java code:

    Date date = new Date();

    Template page:

    <p th:text="${#dates.year(date)}"></p>

    Result page:

    <p>2019</p>

    java code:

    Date date = new Date();

    Template page:

    <p th:text="${#dates.dayOfWeek(date)}"></p>      

    Result page:

    <p>5</p>

    java code:

    Date date = new Date();

    Template page:

    <p th:text="${#dates.dayOfWeekName(date)}"></p> 

    Result page:

    <p>Thursday</p>

    java code:

    Date date = new Date();

    Template page:

    <p th:text="${#dates.dayOfWeekNameShort(date)}"></p>

    Result page:

    <p>Thursday</p>

    java code:

    Date date = new Date();

    Template page:

    <p th:text="${#dates.hour(date)}"></p>

    Result page:

    <p>10</p>

    java code:

    Date date = new Date();

    Template page:

    <p th:text="${#dates.minute(date)}"></p>

    Result page:

    <p>10</p>

    java code:

    Date date = new Date();

    Template page:

    <p th:text="${#dates.second(date)}"></p>

    Result page:

    <p>45</p>

    java code:

    Date date = new Date();

    Template page:

    <p th:text="${#dates.millisecond(date)} "></p>

    Result page:

    <p>853</p>

    Generation Date Action

    Template page:

    <p th:text="${#dates.createNow()}"></p>

    Result page:

    <p>Thu May 30 10:15:55 CST 2019</p>

    Template page:

    <p th:text="${#dates.format(#dates.createNow())}"></p>

    Result page:

    <p>May 30, 2019, 10:1555 seconds </p>

    Template page:

    <p th:text="${#dates.create('2019','05','30')}"></p>

    Result page:

    <p>Thu May 30 00:00:00 CST 2019</p>

    Template page:

    <p th:text="${#dates.create('2019','05','31','10','18')}"></p>

    Result page:

    <p>Fri May 31 10:18:00 CST 2019</p>

    Template page:

    <p th:text="${#dates.create('2019','05','30','10','18','34')}"></p>

    Result page:

    <p>Thu May 30 10:18:34 CST 2019</p>

    Template page:

    <p th:text="${#dates.createToday()}"></p>

    Result page:

    <p>Thu May 30 00:00:00 CST 2019</p>

    #numbers

    Handles the conversion of digital data.Include:

    • Complement 0 (formatInteger) for digits that are not large enough
    • Set thousands separator (formatInteger)
    • FormDecimal
    • Set the percent sign (formatPercent)
    • Generate array (sequence)

    Code demonstration:

        @RequestMapping("/numbers")
        public String numbers(Model model) throws ParseException{
            return "/course/numbers";
        }

    Number to complement 0

    Template code:

    <p th:text="${#numbers.formatInteger('123',4)}"></p>

    Result page:

    <p>0123</p>

    Template code:

    <p th:text="${#numbers.formatInteger('123',3)}"></p>

    Result page:

    <p>123</p>

    Template code:

    <p th:text="${#numbers.formatInteger('123',2)}"></p>

    Result page:

    <p>123</p>

    Java Code

        @RequestMapping("/numbers")
        public String numbers(Model model) throws ParseException{
            List<Integer> numList = new ArrayList<Integer>();
            numList.add(1);
            numList.add(12);
            numList.add(13);
            model.addAttribute("numList",numList);
            return "/course/numbers";
      }

    Template code:

    <p th:text="${#numbers.listFormatInteger(numList,3)}"></p>

    Result page:

    <p>[001, 012, 013]</p>

    Thousands separator operation
    Template code:

    <p th:text="${#numbers.formatInteger('1000',2,'POINT')}"></p>

    Result page:

    <p>1.000</p>

    Template code:

    <p th:text="${#numbers.formatInteger('1000',6,'POINT')}"></p>

    Result page:

    <p>001.000</p>

    Template code:

    <p th:text="${#numbers.formatInteger('1000',7,'POINT')}"></p>

    Result page:

    <p>0.001.000</p>

    Template code:

    <p th:text="${#numbers.formatInteger('1000',2,'COMMA')}"></p>

    Result page:

    <p>1,000</p>

    Template code:

    <p th:text="${#numbers.formatInteger('1000',2,'WHITESPACE')}"></p>

    Result page:

    <p>1 000</p>

    Template code:

    <p th:text="${#numbers.formatInteger('1000',2,'NONE')}"></p>

    Result page:

    <p>1000</p>

    Template code:

    <p th:text="${#numbers.formatInteger('1000',2,'DEFAULT')}"></p>

    Result page:

    <p>1,000</p>

    Precise decimal operation
    Template code:

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

    Result page:

    <p>010.12</p>

    Template code:

    <p th:text="${#numbers.formatDecimal('1000.123',5,'POINT',2,'COMMA')}"></p>

    Result page:

    <p>01.000,12</p>

    Money Display Symbol Operation

    Template code:

    <p th:text="${#numbers.formatCurrency('1000')}"></p>

    Result page:

    <p>¥1,000.00</p>

    Percentage operation
    Template code:

    <p th:text="${#numbers.formatPercent('0.2',2, 4)}"></p>

    Result page:

    <p>20.0000%</p>

    Template code:

    <p th:text="${#numbers.formatPercent('0.2',3, 2)}"></p>

    Result page:

    <p>020.00%</p>

    Generate Array Operation

    Template code:

    <div th:each="num : ${#numbers.sequence(0,4)}" >
              <p th:text="${num}"></p>
    </div>

    Result page:

    <div><p>0</p></div>
    <div><p>1</p></div> 
    <div><p>2</p></div>
    <div><p>3</p></div>
    <div><p>4</p></div>

    Template code:

    <div th:each="num : ${#numbers.sequence(0,4,1)}" >
             <p th:text="${num}"></p>
    </div>

    Result page:

    <div><p>0</p></div>
    <div><p>1</p></div> 
    <div><p>2</p></div>
    <div><p>3</p></div>
    <div><p>4</p></div>

    Template code:

    <div th:each="num : ${#numbers.sequence(0,10,2)}" >
             <p th:text="${num}"></p>
    </div>

    Result page:

    <div><p>0</p></div>
    <div><p>2</p></div>
    <div><p>4</p></div>

    #strings

    Processing String related operations, including:

    • String Conversion (toString)
    • Check if the string is empty (isEmpty)
    • String is a blank substitution operation (defaultString)
    • Check that the string contains a string (contains containsIgnoreCase)
    • Check whether the string begins or ends with a fragment (startsWith endsWith)
    • substring substringAfter
    • replace
    • prepend append
    • Change case (toUpperCase to LowerCase)
    • Split and combine strings (arrayJoin in arraySplit)
    • Strip (trim)
    • abbreviate text
    • String concat

    Code demonstration:
    java code

    @RequestMapping("/strings")
        public String strings(Model model){
            Object object = "123";
            model.addAttribute("object",object);
            
            List<Integer> numList = new ArrayList<Integer>();
            numList.add(1);
            numList.add(12);
            numList.add(13);
            model.addAttribute("numList",numList);
    }

    Java Code

    Object object = "123";

    Template code:

    <p th:text="${object}"></p>

    Result page:

    <p>123</p>

    toString operation

    Java Code

    Object object = "123";

    Template code:

    <p th:text="${#strings.toString(object)}"></p>

    Result page:

    <p>123</p>

    Java Code

    List<Integer> numList = new ArrayList<Integer>();
        numList.add(1);
        numList.add(12);
        numList.add(13);

    Template code:

    <p th:text="${#strings.toString(numList)}"></p>

    Result page:

    <p>[1, 12, 13]</p>

    isEmpty operation
    Java Code

    String name = null;

    Template code:

    <p th:text="${#strings.isEmpty(name)}"></p>

    Result page:

    <p>true</p>

    Java Code

    List<String> nameList = new ArrayList<String>();
            nameList.add("1");
            nameList.add(null);

    Template code:

    <p th:text="${#strings.listIsEmpty(nameList)}"></p>

    Result page:

    <p>[false, true]</p>

    Java Code

    Set<String> nameSet = new HashSet<String>();
            nameSet.add(null);
            nameSet.add("1");

    Template code:

    <p th:text="${#strings.setIsEmpty(nameSet)}"></p>

    Result page:

    <p>[true, false]</p>

    defaultString operation
    Java Code

    String name = null;

    Template code:

    <p th:text="${#strings.defaultString(text,'This value is null')}'></p>

    Result page:

    <p>The value is null</p>

    Java Code

    List<String> nameList = new ArrayList<String>();
            nameList.add("1");
            nameList.add(null);

    Template code:

    <p th:text="${#strings.listDefaultString(textList,'This value is null')}'></p>

    Result page:

    <p>[abc, The value is null]</p>

    contains operation
    Template code:

    <p th:text="${#strings.contains('abcez','ez')}"></p>

    Result page:

    <p>true</p>

    Template code:

    <p th:text="${#strings.containsIgnoreCase('abcEZ','ez')}"></p>

    Result page:

    <p>true</p>

    startsWith endsWith operation

    Template code:

    <p th:text="${#strings.startsWith('Donabcez','Don')}"></p>

    Result page:

    <p>true</p>

    Template code:

    <p th:text="${#strings.endsWith('Donabcezn','n')}"></p> 

    Result page:

    <p>true</p>

    indexOf operation
    Template code:

    <p th:text="${#strings.indexOf('abcefg','e')}"></p> 

    Result page:

    <p>3</p>

    substring operation
    Template code:

    <p th:text="${#strings.substring('abcefg',3,5)}"></p>   

    Result page:

    <p>ef</p>

    replace operation
    Template code:

    <p th:text="${#strings.replace('lasabce','las','ler')}"></p>

    Result page:

    <p>lerabce</p>

    prepend operation
    Template code:

    <p th:text="${#strings.prepend('abc','012')}"></p>

    Result page:

    <p>012abc</p>

    append operation
    Template code:

    <p th:text="${#strings.append('abc','456')}"></p>

    Result page:

    <p>abc456</p>

    toUpperCase operation
    Template code:

    <p th:text="${#strings.toUpperCase('abc')}"></p>

    Result page:

    <p>ABC</p>

    toLowerCase operation
    Template code:

    <p th:text="${#strings.toLowerCase('ABC')}"></p>  

    Result page:

    <p>abc</p>

    length operation
    Template code:

    <p th:text="${#strings.length('abc')}"></p>

    Result page:

    <p>3</p>

    trim operation
    Template code:

    <p th:text="${#strings.trim(' abc ')}"></p>

    Result page:

    <p>abc</p>

    abbreviate operation
    Template code:

    <p th:text="${#strings.abbreviate('12345678910',10)}"></p>

    Result page:

    <p>1234567...</p>

    #objects

    Operations that process Object objects include obj returning no null change value If null returns default value (nullSafe)
    java code

    @RequestMapping("/objects")
    public String objects(Model model){
      Object obj = null;
      model.addAttribute("obj",obj);
    }

    Template code:

    <p th:text="${#objects.nullSafe(obj,'the object is null')}'></p>

    Result page:

    <p>The object is null</p>

    #bools

    The operation that determines whether the object is a ture or a false.

    • Number 1 is true and 0 is false.
    • "on" is true and "off" is false;
    • "True" is true and "false" is false;

    isTrue operation
    Template code:

    <p th:text="${#bools.isTrue(true)} "></p>

    Result page:

    <p>true</p>

    Template code:

    <p th:text="${#bools.isTrue(false)} "></p>

    Result page:

    <p>false</p>

    Template code:

    <p th:text="${#bools.isTrue('on')} "></p>

    Result page:

    <p>true</p>

    Template code:

    <p th:text="${#bools.isTrue('off')} "></p>

    Result page:

    <p>false</p>

    Template code:

    <p th:text="${#bools.isTrue('true')} "></p>

    Result page:

    <p>true</p>

    Template code:

    <p th:text="${#bools.isTrue('false')} "></p>

    Result page:

    <p>false</p>

    Template code:

    <p th:text="${#bools.isTrue(1)} "></p>

    Result page:

    <p>true</p>

    Template code:

    <p th:text="${#bools.isTrue(0)} "></p>

    Result page:

    <p>false</p>

    #arrays

    A built-in object that handles operations related to arrays, including:

    • Convert the array toStringArray to IntegerArray,
    • Gets the length of the array,
    • Determine if the array is empty (isEmpty)
    • Whether to include an element (contains)
    • Whether to include a batch of elements (containsAll)

    Operations such as toStringArray accept Object objects, and containsAll accepts parameters that support arrays and collections for a batch of elements.

    toStringArray operation
    java code

    @RequestMapping("/arrays")
    public String arrays(Model model){
      List<String> object = new ArrayList<String>();
      object.add("1");
      object.add("2");
      model.addAttribute("object",object);
    }

    Template code:

     <p th:text="${#arrays.toStringArray(object)} "></p>

    Result page:

    <p>[Ljava.lang.String;@3cca655d</p>

    length operation
    java code

    Integer[] array = {1,2,3};

    Template code:

     <p th:text="${#arrays.length(array)} "></p>

    Result page:

    <p>3</p>

    isEmpty operation
    java code

    Integer[] array = {1,2,3};

    Template code:

     <p th:text="${#arrays.isEmpty(array)} "></p>

    Result page:

    <p>false</p>

    contains operation
    java code

    Integer[] array = {1,2,3};

    Template code:

    <p th:text="${#arrays.contains(array,1)} "></p>

    Result page:

    <p>true</p>

    containsAll operation
    java code

    Integer[] array = {1,2,3};
    Integer[] array2 = {1,3};

    Template code:

     <p th:text="${#arrays.containsAll(array,array2)} "></p>

    Result page:

    <p>true</p>

    #lists

    Built-in objects that handle list-related operations, including:

    • Calculated length (size)
    • Check if list is empty (isEmpty)
    • Check if the element is included in the list (contains,containsAll)
    • Sort copies of a given list

    java code

    @RequestMapping("/lists")
    public String lists(Model model){
       List<Integer> list = new ArrayList<Integer>();
       list.add(1);
       list.add(3);
       list.add(2);
       model.addAttribute("list",list);
     }

    Template code:

    <p th:text="${#lists.size(list)} "></p>

    Result page:

    <p>3</p>

    java code:

     List<Integer> list = new ArrayList<Integer>();
     list.add(1);
     list.add(3);
     list.add(2);

    Template code:

    <p th:text="${#lists.isEmpty(list)} "></p>

    Result page:

    <p>false</p>
    

    java code:

     List<Integer> list = new ArrayList<Integer>();
     list.add(1);
     list.add(3);
     list.add(2);

    Template code:

    <p th:text="${#lists.contains(list, 1)}"></p>

    Result page:

    <p>true</p>

    java code:

    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(3);
    list.add(2);
    List<Integer> list2 = new ArrayList<Integer>();
    list2.add(1);
    list2.add(2);

    Template code:

    <!-- elements Can be a collection of arrays list -->
    <p th:text="${#lists.containsAll(list,list2)}"></p>

    Result page:

    <p>true</p>

    java code:

    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(3);
    list.add(2);

    Template code:

    <p th:text="${#lists.sort(list)}"></p>

    Result page:

    <p>[1, 2, 3]</p>

    #sets

    Built-in objects that handle set-related operations, including:

    • Convert to Set(toSet)
    • Calculated length (size)
    • Check if set is empty (isEmpty)
    • Check if the element is included in the set (contains,containsAll)

    size operation

    java code

    @RequestMapping("/sets")
    public String sets(Model model){
       Set<Integer> set = new HashSet<Integer>();
       set.add(1);
       set.add(2);
       set.add(3);
       set.add(4);
       model.addAttribute("set",set);
     }

    Template code:

    <p th:text="${#sets.size(set)} "></p>

    Result page:

    <p>3</p>
    

    isEmpty operation

    java code:

    Set<Integer> set = new HashSet<Integer>();
      set.add(1);
      set.add(2);
      set.add(3);
      set.add(4);

    Template code:

    <p th:text="${#sets.isEmpty(set)} "></p>

    Result page:

    <p>false</p>
    

    contains operation

    java code:

    Set<Integer> set = new HashSet<Integer>();
      set.add(1);
      set.add(2);
      set.add(3);
      set.add(4);

    Template code:

    <p th:text="${#sets.contains(set, 1)}"></p>

    Result page:

    <p>true</p>
    

    containsAll operation

    java code

    Set<Integer> set = new HashSet<Integer>();
      set.add(1);
      set.add(2);
      set.add(3);
      set.add(4);
      
    Integer[] elements = {1,2};
    model.addAttribute("elements",elements);

    Template code:

    <p th:text="${#sets.containsAll(set, elements)}"></p>

    Result page:

    <p>true</p>
    
    

    sort operation

    java code:

    Set<Integer> set = new HashSet<Integer>();
      set.add(1);
      set.add(2);
      set.add(3);
      set.add(4);

    Template code:

    <p th:text="${#lists.sort(list)}"></p>

    Result page:

    <p>[1, 2, 3]</p>
    

    #maps

    Built-in objects that handle map-related operations, including:

    • Calculated length (size)
    • Check if map is empty (isEmpty)
    • Check if the map contains a key or value (containsKey,containsAllKeys,containsValue)

    java code:

    @RequestMapping("/maps")
    public String maps(Model model){
       Map<String,Integer> map = new HashMap<String,Integer>();
       map.put("1",1);
       map.put("2",2);
       map.put("3",3);
       model.addAttribute("map",map);
    }

    Template code:

    <p th:text="${#maps.size(map)} "></p>

    Result page:

    <p>3</p>

    java code:

       Map<String,Integer> map = new HashMap<String,Integer>();
       map.put("1",1);
       map.put("2",2);
       map.put("3",3);

    Template code:

    <p th:text="${#maps.isEmpty(map)} "></p>

    Result page:

    <p>false</p>

    java code:

       Map<String,Integer> map = new HashMap<String,Integer>();
       map.put("1",1);
       map.put("2",2);
       map.put("3",3);

    Template code:

    <p th:text="${#maps.containsKey(map, '1')}"></p>

    Result page:

    <p>true</p>

    java code:

    Map<String,Integer> map = new HashMap<String,Integer>();
       map.put("1",1);
       map.put("2",2);
       map.put("3",3);
    String[] keys = {"1","2"};
    model.addAttribute("keys",keys);

    Template code:

    <!--keys can be arrays or collections-->
    <p th:text="${#maps.containsAllKeys(map, keys)}"></p>

    Result page:

    <p>true</p>

    java code:

    Map<String,Integer> map = new HashMap<String,Integer>();
       map.put("1",1);
       map.put("2",2);
       map.put("3",3);

    Template code:

    <p th:text="${#maps.containsValue(map, 2)}"></p>

    Result page:

    <p>true</p>

    java code:

    Map<String,Integer> map = new HashMap<String,Integer>();
       map.put("1",1);
       map.put("2",2);
       map.put("3",3);
    Integer[] values = {1,2};
    model.addAttribute("values",values);

    Template code:

    <! -- Values can be arrays or collections-->
    <p th:text="${#maps.containsAllValues(map, values)}"></p>

    Result page:

    <p>true</p>

    #aggregates

    Users handle some statistical operations on collections or arrays, including:

    • Sum
    • Average (avg)
    • Arrays or collections dealing with packaging or basic types

    Summation operation

    java code:

    @RequestMapping("/aggregates")
    public String aggregates(Model model){
       Integer[] array = {1,2,3,4};
       model.addAttribute("array",array);
       return "/course/aggregates";
    }

    Template code:

    <p th:text="${#aggregates.sum(array)} "></p>

    Result page:

    <p>10</p>

    java code:

    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);

    Template code:

    <p th:text="${#aggregates.sum(list)} "></p>

    Result page:

    <p>10</p>

    Average operation

    java code:

     Integer[] array = {1,2,3,4};

    Template code:

    <p th:text="${#aggregates.avg(array)} "></p>

    Result page:

    <p>2.5</p>

    java code:

    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);

    Template code:

    <p th:text="${#aggregates.avg(list)} "></p>

    Result page:

    <p>2.5</p>

    Summary

    This article describes the basic use of Thymeleaf, inline, template layout, and predefined tool objects.Overall, Thymeleaf is grammatical or powerful, but I don't want to overwhelm Amway that you use Thymeleaf, as Thymeleaf officially said: "In any case, the best way to compare technologies is to use them yourself and feel which is best for you!"You can also choose to use Velocity or FreeMarker.

    Code Samples

    For a code sample, look under the course package under spring-boot-2.x-thymeleaf in my springbootexamples GitHub repository.

    GitHub: https://github.com/zhuoqianmingyue/springbootexamples

    Reference:

    https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html

    https://blog.csdn.net/liubin5620/article/details/80470619

    posted on 2019-09-17 06:31 Bright moon at table Read (...) comments (...) edit Collection

    Powered by:
    Blog Park
    Copyright_the moon at your desk in 2019
    Powered by .NET Core 3.0.0-preview9-19423-09 on Linux

Keywords: Java Thymeleaf Fragment Attribute

Added by romeo on Tue, 17 Sep 2019 01:54:03 +0300