In the previous article Springboot (ii) : Web integrated development briefly introduced thymeleaf, this article will be more comprehensive and detailed introduction to the use of Thymeleaf. Thymeleaf is a new generation of template engine. It is recommended to use thymeleaf as the front-end template engine in spring4.0.

Thymeleaf introduction

In short, Thymeleaf is a templating engine similar to Velocity and FreeMarker that can completely replace JSPS. Compared to other templating engines, it has three attractive features:

  • 1.Thymeleaf works both on and off the Internet, that is, it allows artists to view static pages in the browser and programmers to view dynamic pages with data in the server. This is because it supports HTML prototypes and then adds additional attributes to HTML tags to achieve the template + data presentation. Browsers ignore undefined tag attributes when interpreting HTML, so Thymeleaf’s template can run statically; When data is returned to the page, the Thymeleaf tag dynamically replaces the static content and makes the page display dynamically.

  • 2. Out-of-the-box features of Thymeleaf. It provides standard and Spring standard two dialects, can directly apply template to achieve JSTL, OGNL expression effect, avoid every day set template, the JSTL, change label trouble. Developers can also extend and create custom dialects.

  • 3.Thymeleaf provides the Spring standard dialect and an optional module perfectly integrated with SpringMVC to quickly implement form binding, property editor, internationalization and other functions.

Standard expression syntax

They fall into four categories:

  • 1. Variable expressions
  • 2. Select or asterisk expressions
  • 3. Text internationalization expressions
  • 4. URL expression

Variable expression

Variable expressions are OGNL expressions or Spring EL expressions (also called Model Attributes in Spring terminology). ${session.user.name}

They will be represented as an attribute of the HTML tag:

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

Select the (asterisk) expression

Select expressions are much like variable expressions, except that they are executed with a pre-selected object instead of a context variable container (map), as follows: *{customer.name}

The specified object is defined by the th:object property:

    <div th:object="${book}">.<span th:text="*{title}">.</span>.</div>Copy the code

Text internationalization expression

Literal internationalization expressions allow us to get locale text information (.properties) from an external file, index Value with Key, and optionally provide a set of parameters.

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

You can find expression code like this in the template file:

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

URL expression

URL expression refers to adding useful context or reply information to a URL, a process often referred to as URL rewriting. @{/order/list} URL can also set parameters: @{/order/details(id=${orderId})} relative path: @{.. /documents/report}

Let’s look at these expressions:

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

What’s the difference between variable expressions and asterisks?

Without considering the context, there is no difference; Asterisk syntax evaluation is expressed on the selected object, not the entire context What is the selected object? Is the value of the parent tag, as follows:

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

This is exactly equivalent to:

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

Of course, the dollar sign and asterisk syntax can be mixed:

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

Syntax supported by expressions

Literals.

  • Text literals:'one text', 'Another one! ',...
  • Number literals:0, 34, 3.0, 12.3,...
  • Boolean literals:true, false
  • Null literal:null
  • Literal tokens:One, sometext, main,...

Text operations

  • String concatenation:+
  • Text substitution (Literal substitutions) :|The name is ${name}|

(4) Arithmetic operations

  • Binary operators:+, -, *, /, %
  • Minus sign (unary operator):-

Boolean operations

  • Binary operators:and, or
  • Boolean negation (unary operator) Boolean negation (unary operator):! , not

Word order and Equality

  • Comparators:>, <, >=, <= (gt, lt, ge, le)
  • Equality Operators:= =,! = (eq, ne)

Conditional Operators

  • If-then: (if) ? (then)
  • If-then-else: (if) ? (then) : (else)
  • Default: (value) ? :(defaultvalue)

All of these characteristics can be combined and nested:

'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ? : 'Unknown'))Copy the code

What are commonly used TH labels?

The keyword Function is introduced case
th:id Replace the id <input th:id="'xxx' + ${collect.id}"/>
th:text Textual substitution <p th:text="${collect.description}">description</p>
th:utext Support HTML text replacement <p th:utext="${htmlcontent}">conten</p>
th:object Replace the object <div th:object="${session.user}">
th:value Attribute assignment <input th:value="${user.name}" />
th:with Variable assignment operations <div th:with="isEven=${prodStat.count}%2==0"></div>
th:style Set the style th:style="'display:' + @{(${sitrue} ? 'none' : 'inline-block')} + ''"
th:onclick Click on the event th:onclick="'getCollect()'"
th:each Attribute assignment tr th:each="user,userStat:${users}">
th:if Judge conditions <a th:if="${userId == collect.userId}" >
th:unless Th :if <a th:href="@{/login}" th:unless=${session.user ! = null}>Login</a>
th:href The link address <a th:href="@{/login}" th:unless=${session.user ! = null}>Login</a> />
th:switch Multiplexing is used with th:case <div th:switch="${user.role}">
th:case Th: a branch of switch <p th:case="'admin'">User is an administrator</p>
th:fragment The layout tag defines a snippet of code that can be referenced elsewhere <div th:fragment="alert">
th:include Layout tabs to replace content into imported files <head th:include="layout :: htmlhead" th:with="title='xx'"></head> />
th:replace Layout the label, replacing the entire label into the imported file <div th:replace="fragments/header :: title"></div>
th:selected Selected The selection box is selected th:selected="(${xxx.id} == ${configObj.dd})"
th:src Image class address introduction <img class="img-responsive" alt="App Logo" th:src="@{/img/logo.png}" />
th:inline Js scripts can be defined using variables <script type="text/javascript" th:inline="javascript">
th:action The address to submit the form <form action="subscribe.html" th:action="@{/subscribe}">
th:remove Delete an attribute <tr th:remove="all"> 1. All :remove contain tags and all children. 2. Body: does not contain the tag to delete, but deletes all of its children. 3. Tag: Contains the removal of the tag, but does not remove its children. 4. All-but-first: Delete all children that contain tags except the first one. 5. None: Do nothing. This value is useful for dynamic evaluation.
th:attr Sets the label properties. Multiple properties can be separated by commas Such asth:attr="src=@{/image/aa.jpg},title=#{logo}"This label is not very elegant and is rarely used.

There are many other tags, but only the most common ones are listed here. Since a tag can contain multiple TH 😡 attributes, the order in which they take effect is: Include, each I should if/in the way/switch/case, with, attr/attrprepend/attrappend, value/href, SRC, etc, the text/utext, fragments, remove.

Several common use methods

1. Assignment and string concatenation

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

There is another succinct way to write string concatenation

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

2. If/Unless

Thymeleaf uses the th:if and th:unless attributes for conditional judgment. In the following example, the tag is displayed only if the condition in th:if is true:

<a th:if="${myself=='yes'}" > </i> </a>
<a th:unless=${session.user! =null} th:href="@{/login}" >Login</a>Copy the code

Th :unless, as opposed to th:if, displays the content of the expression only if the condition is not true.

You can also use (if)? (then) : (else) This syntax determines what is displayed

3. For loop

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

IterStat is called a state variable and has the following attributes:

  • Index: the index of the current iteration (counting from 0)
  • Count: Index of the current iteration (counting from 1)
  • Size: indicates the size of the iterated object
  • Current: indicates the current iteration variable
  • Even /odd: Boolean if the current loop is even/odd (counting from 0)
  • First: Boolean value for whether the current loop is the first
  • Last: Boolean value, whether the current loop is the last

4, URL

URL plays an important role in Web application templates. It should be noted that Thymeleaf uses the @{… }. If you need Thymeleaf to render the URL, be sure to use th:href, th: SRC, etc. Here is an example

<! -- Will produce 'http://localhost:8080/standard/unread' (plus rewriting) -->
 <a  th:href="@{/standard/{type}(type=${type})}">view</a>

<! -- Will produce '/gtvg/order/3/details' (plus rewriting) -->
<a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>Copy the code

Set the background

<div th:style="'background:url(' + @{/
       
        } + '); '"
       ></div>Copy the code

Change the background based on the property value

 <div class="media-object resource-card-image"  th:style="'background:url(' + @{(${collect.webLogo}=='' ? 'img/favicon.png' : ${collect.webLogo})} + ')'" ></div>Copy the code

A few notes:

  • Last of the URL in the above example(orderId=${o.id})This syntax avoids string concatenation, greatly improving readability
  • @ {... }Can be passed in the expression{orderId}Access the orderId variable in the Context
  • @{/order}Is the relative path of the Context, which is automatically added to the current Web application’s Context name during rendering. If the Context name is app, then the result should be /app/order

5. Inline JS

Inline text: [[…]] Inline text must be activated with th:inline=”text/javascript/ None “. Th: Inline can be used within a parent tag, or even as a body tag. Inline text, although less code than TH :text, is not conducive to prototype display.

<script th:inline="javascript">
/ * 
      . var username =/*[[${sesion.user.name}]]*/ 'Sebastian';
var size = /*[[${size}]]*/ 0; .> * / / *]]
</script>Copy the code

Js additional code:

/*[+
var msg = 'This is a working application';
+]*/Copy the code

Js remove code:

[/ * - * /
var msg = 'This is a non-working template';
/ * - * /Copy the code

6. Embedded variables

To make templates easier to use, Thymeleaf also provides a series of Utility objects (built into Context) that can be accessed directly via # :

  • Dates:Date function method class for java.util.date.
  • calendars : Similar to #dates, for java.util.calendar
  • numbers : A function method class that formats numbers
  • strings : The function of a string object class, the contains, startWiths, prepending/appending etc.
  • objects: Function class operations on objects.
  • bools: A functional method of evaluating a Boolean value.
  • The arrays:Function class methods on arrays.
  • lists: Lists function class method
  • sets
  • maps

Here is an example of some common methods:

dates

/*
 * Format date with the specified pattern
 * Also works with arrays, lists or sets
 */
${#dates.format(date, 'dd/MMM/yyyy HH:mm')}
${#dates.arrayFormat(datesArray, 'dd/MMM/yyyy HH:mm')}
${#dates.listFormat(datesList, 'dd/MMM/yyyy HH:mm')}
${#dates.setFormat(datesSet, 'dd/MMM/yyyy HH:mm')}

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

/*
 * Create a date (java.util.Date) object for the current date (time set to 00:00)
 */
${#dates.createToday()}Copy the code

strings

/*
 * Check whether a String is empty (or null). Performs a trim() operation before check
 * Also works with arrays, lists or sets
 */
${#strings.isEmpty(name)}
${#strings.arrayIsEmpty(nameArr)}
${#strings.listIsEmpty(nameList)}
${#strings.setIsEmpty(nameSet)}

/*
 * Check whether a String starts or ends with a fragment
 * Also works with arrays, lists or sets
 */
${#strings.startsWith(name,'Don')}                  // also array*, list* and set*
${#strings.endsWith(name,endingFragment)}           // also array*, list* and set*

/*
 * Compute length
 * Also works with arrays, lists or sets
 */
${#strings.length(str)}

/*
 * Null-safe comparison and concatenation
 */
${#strings.equals(str)}
${#strings.equalsIgnoreCase(str)}
${#strings.concat(str)}
${#strings.concatReplaceNulls(str)}

/*
 * Random
 */
${#strings.randomAlphanumeric(count)}Copy the code

Use thymeleaf layout

Using thymeleaf layout is very convenient

Defining code snippets

<footer th:fragment="copy"> 
&copy; 2016
</footer>Copy the code

Introduce: anywhere on the page

<body> 
  <div th:include="footer :: copy"></div>
  <div th:replace="footer :: copy"></div>
 </body>Copy the code

Th :include is different from th:replace. Include is just loading. Replace is replacing

The HTML returned is as follows:

<body> 
   <div> &copy; 2016 </div> 
  <footer>&copy; 2016 </footer> 
</body>Copy the code

Here is a common background page layout, the entire page is divided into header, tail, menu bar, hidden bar, click the menu to change only the content area of the page

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

Any page that wants to use a layout value like this simply replaces the Content module shown above

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

You can also pass in a reference to a template

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

Layout is the address of the file, if you have a folder you can write fileName/layout:htmlhead Htmlhead is a defined code fragment like th:fragment=”copy”

Source of case

There is an open source project that uses almost all of the tags and layouts described here: CloudFavorites

reference

Thymeleaf Official Guide to the new Generation of Java Templating engine Thymeleaf Basic Knowledge thymeleaf summary article Thymeleaf templates using Thymeleaf learning notes


Like my article, please follow my official account