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.
- th:text text text replacement does not resolve html
- 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&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"> © 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" > © 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"> © 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 CodeString 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 CodeString 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 codeInteger[] array = {1,2,3};
Template code:
<p th:text="${#arrays.length(array)} "></p>
Result page:
<p>3</p>
isEmpty operation
java codeInteger[] array = {1,2,3};
Template code:
<p th:text="${#arrays.isEmpty(array)} "></p>
Result page:
<p>false</p>
contains operation
java codeInteger[] array = {1,2,3};
Template code:
<p th:text="${#arrays.contains(array,1)} "></p>
Result page:
<p>true</p>
containsAll operation
java codeInteger[] 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 LinuxAdded by romeo on Tue, 17 Sep 2019 01:54:03 +0300