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">
© 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> © 2016 </div>
<footer>© 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