Template engine Thymeleaf? This one is enough

Template engine Thymeleaf? This one is enough

Write in front

The html in the template page needs to declare the Thymeleaf namespace, the specific code is as follows

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

For example, when we write ThymeLeaf code in Idea, there will be related code hints.

th:text and th:utext

These two tags are used for the display operation of the text content. They have similar functions, except whether they will be parsed.

  • th:text does not parse html for text replacement
  • th:utext will parse html for text replacement

Example

We write a code like this

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

For th:text , write like this in the HTML page, as follows

<p th:text= "text tag: + ${msg} " ></p> Copy code

Because the text will not be parsed, the following results will be obtained

<p>text tag: <h1>I am h1</h1></p> Copy code

For th:utext in the HTML page, write as follows

<p th:utext= "utext tag: + ${msg} " ></p> Copy code

Because utext will be parsed, the following results will be obtained.

Of course, here is a reminder that the effect of using + and | | is the same, as shown in the following code

<p th:utext= "utext tag: + ${msg} " ></p> <p th:utext= "|utext tag: ${msg} |" ></p> Copy code

String splicing

The splicing string is spliced by + or |, we are requested to write such a code first and use the HTML template

@RequestMapping( "/th" ) public String th(Model model){ model.addAttribute( "a" ,1); model.addAttribute( "b" ,2); return "/course/th" ; } Copy code
#Template one <p th:text= " ${a} + ${b} " ></p> #Template two <p th:text= "| ${a} ${b} |" ></p > #Template three <p th:text= " ${a} > ${b} " ></p> Copy code

The results are as follows

#Result One <p>3</p> #Result two <p>1 2</p> #Result three <p> false </p> Copy code

We changed a java code and used the following HTML template

@RequestMapping( "/th" ) public String th(Model model){ model.addAttribute( "flag" , true ); return "/course/th" ; } Copy code
<p th:text= "! ${flag} " ></p> Copy code

Get the following results:

<p>false</p>

*{ } and ${ } expressions

In general, *{ } is the same as ${ }, but *{ } is generally used together with th:object to complete the abbreviation of object properties. Let s take an example, using the following java code

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

Template operation

#Use ${...} operation <p th:text= " ${user.name} " ></p> <p th:text= " ${user.age} " ></p> #Use *{...} operation <p th:text= "*{user.name}" ></p> <p th:text= "*{user.age}" ></p> Copy code

The two obtained results are as follows

<p>ljk</p> <p>18</p> Copy code

Let's try to use *{...} special operations

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

You will get the following result page:

<p>ljk</p> <p>18</p> Copy code

#{ }expression

Used to read internationalized message.properties properties and define the message_zh_CN.properties configuration file


Define internationalization processing conversion processing class

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

Define the controller for internationalization processing

@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 user information to session request.getSession( true ).setAttribute( "user" , new User( "I am" , "haha" , "CHINA" , null)); localeResolver.setLocale(request,response,Locale.CHINA); return "productList" ; } } Copy code

If message_en_US.properties and message_zh_CN.properties are not defined, the information in message.properties will be taken by default. If Locale = Locale.CHINA, take message_zh_CN.properties. If Locale = Locale.US, take message_en_US.properties. Let's test it with the following template code

<P TH: UTEXT = "# {home.welcome ( $ {session.user.name} )}" >! Our available for purchase to Grocery Store, Sebastian </P> copy the code

Get the following result

Welcome to our grocery store, I ha ha copy the code

~{ } Fragment expression

This is generally used together with the template layout syntax. For specific usage, please see the template layout tutorial below.

@{ }Link URL expression

It is generally used in combination with th:href and th:src to display URL links in Web applications. Through @{ } expressions, Thymeleaf can help us splice the full path accessed by web applications, and at the same time we can splice the parameters through ()

Template code:

#Template one <img th:src= "@{/images/gtvglogo.png}" /> #Template two <a th:href= "@{/product/comments(prodId= ${prod.id} )}" >View</a> #Template Three <a th:href= "@{/product/comments(prodId= ${prod.id} ,prodId2= ${prod.id} )}" >View</a> Copy Code

Results page:

#Result one <img src= "/sbe/images/gtvglogo.png" > #Result two <a href= "/sbe/product/comments?prodId=2" >View</a> #Result three <a href= "/sbe/product/comments?prodId=2&prodId2=2" >View</a> Copy code

th:if and th:unless

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

java code:

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

Template page:

#Template one <p th: if = " ${flag} " > if judgment</p> #Template two <p th:unless= "! $ {} In Flag " > The unless Analyzing </p> copy the code

Results page:

<p> if judgment</p> <p>Unless judgment</p> Copy code

switch

  • th:switch We can use switch to complete similar conditional expression operations.

java code:

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

Template page:

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

Results page:

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

for loop

  • th:each traverse the collection

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" ; } Copy code

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> Copy code

Results page:

explain here

th:class="${strStat.odd}?'odd'"
, We can use the convenient variable name +Stat to get whether the index is the first or the last, etc.
The convenient variable name +Stat is called a state variable, and its attributes are:

  • index: The iteration index of the current iteration object, starting from 0, this is the index attribute;
  • count: the iteration index of the current iteration object, starting from 1, this is a statistical attribute;
  • size: The total amount of iterated variable elements, which is the size attribute of the iterated object;
  • current: current iteration variable;
  • even/odd: Boolean value, whether the current loop is even/odd (calculated from 0);
  • first: Boolean value, whether the current loop is the first one;
  • last: Boolean value, whether the current loop is the last

th:href

Used to declare the link of the href attribute on the a tag. This syntax will be used with the @{ } expression.
java code

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

Template page

<a href= "../home.html" th:href= "@{/}" >Return to homepage</a> Copy code

Results page:

<a href= "/sbe/" >Return to homepage</a> Copy code

th:class

Used to declare the class attribute information on the label.
java code:

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

Template page:

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

Results page:

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

th:attr

Used to declare html or custom attribute information.

java code:

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

Template page:

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

Results page:

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

th:value

Used to declare value attribute information in html.
java code:

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

Template page:

<INPUT type = "text" TH: value = " $ {name} "/> copy the code

Results page:

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

th:action

Used to declare the action attribute information in the html from tag.
java code:

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

Template page:

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

Results page:

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

th:id

Used to declare htm id attribute information.
java code:

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

Template page:

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

Results page:

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

th:inline

For the syntax used by JavaScript inline operations, please refer to the following introduction about inline operations for details

th:onclick

Used to declare the onclick event in htm.

java code:

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

Template page:

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

Results page:

<p onclick= "showUserInfo()" >Click me</p> to copy the code

th:selected

Used to declare the selected attribute information in htm.

java code:

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

Template page:

<select> <option name= "sex" ></option> <option th:selected= "1 == ${sex} " >Male</option> <option th:selected= "0 == ${sex} " >Female</option> </select> Copy code

Results page:

<select> <option name= "sex" ></option> <option selected= "selected" >Male</option> <option>Female</option> </select> Copy code

th:src

Used to declare the src attribute information in img in htm.

java code:

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

Template page:

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

Results page:

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

th:style

It is used to declare the style information of the tag css in htm.

java code:

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

Template page:

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

Results page:

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

th:with

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

java code:

#Code one @RequestMapping( "/thwith" ) public String thwith(Model model){ model.addAttribute( "today" , new Date()); return "/course/thwith" ; } #Code two @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" ; } Copy code

Template page:

#Template One <p th:with= "df='dd/MMM/yyyy HH:mm'" > Today is: <span th:text= " ${#dates.format(today,df)} " >13 February 2011</span> </p> #Template two <div th:with= "firstEle= ${users[0]} " > <p>The name of the first user is: <span th:text= " ${firstEle.name} " ></span>. </p> </div> Copy code

Results page:

#Result One <span>02/02/2020 06:52</span> #Result two <div> <p> The name of the first user is: <span>ljk</span>. </p> </div> Copy code

Another usage is to use it in the reference fragment with parameters in the template layout as follows:

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

For specific demonstration, please refer to the introduction in the template layout.

Elvis operator

Elvis operation can be understood as a shorthand for simply judging whether it is null or not. If the value is null, the default value is displayed, and if it is not null, the original value is displayed.

java code:

#Code one @RequestMapping( "/elvis" ) public String elvis(Model model){ model.addAttribute( "age" , null); return "/course/elvis" ; } #Code two @RequestMapping( "/elvis" ) public String elvis(Model model){ model.addAttribute( "age2" , 18); return "/course/elvis" ; } Copy code

Template page:

#Template One <p>Age: <span th:text= " ${age} ?:'Age is nll'" ></span></ p> #Template two <p>Age2: <span th:text= " ${age2} ?:'Age is nll'" ></span></p> Copy code

Results page:

#Result One <p>Age: <span>Age is nll</span></p> #Result two <p>Age2: <span>18</span></p> Copy code

Ternary expression

We can use ternary expressions in thymeleaf's syntax. How to use it in th:x? 1 option: 2 options.

java code:

#Code one @RequestMapping( "/threeElementOperation" ) public String threeElementOperation(Model model){ return "/course/threeElementOperation" ; } #Code two @RequestMapping( "/threeElementOperation" ) public String threeElementOperation(Model model){ model.addAttribute( "name" , "ljk" ); return "/course/threeElementOperation" ; } Copy code

Template page:

#Template One <p th:class= "'even'?'even':'odd'" th:text= "'even'?'even':'odd'" ></p> #Template two <p th:value = " ${name eq'ljk'?'Handsome guy':'ugly guy'} " th:text = " ${name eq'ljk'?'Handsome guy':'ugly guy'} " ></p> Copy code

Results page:

# <p class= "even" >even</p> #Result two <p value= "Handsome guy" >Handsome guy</p> Copy code

Conditional expression operation characters:

  • gt: great than (greater than)
  • ge: great equal (greater than or equal to)
  • eq: equal
  • lt: less than
  • le: less equal (less than or equal to)
  • ne: not equal

No-Operation (_)

A special shorthand operation of the Elvis operator, when the displayed value is null, it does nothing.
java code:

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

Template page:

<span TH: text = " $ {name} :? _" > User Authenticated NO </span> copy the code

Results page:

<span>no user authenticated</span> Copy code

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

th:asyncth:autofocusth:autoplay
th:checkedth:controlsth:declare
th:defaultth:deferth:disabled
th:formnovalidateth:hiddenth:ismap
th:loopth:multipleth:novalidate
th:nowrapth:openth:pubdate
th:readonlyth:requiredth:reversed
th:scopedth:seamlessth:selected

For specific HTML5 attributes:

th:abbrth:acceptth:accept-charset
th:accesskeyth:actionth:align
th:altth:archiveth:audio
th:autocompleteth:axisth:background
th:bgcolorth:borderth:cellpadding
th:cellspacingth:challengeth:charset
th:citeth:classth:classid
th:codebaseth:codetypeth:cols
th:colspanth:compactth:content
th:contenteditableth:contextmenuth:data
th:datetimeth:dirth:draggable
th:dropzoneth:enctypeth:for
th:formth:formactionth:formenctype
th:formmethodth:formtargetth:fragment
th:frameth:frameborderth:headers
th:heightth:highth:href
th:hreflangth:hspaceth:http-equiv
th:iconth:idth:inline
th:keytypeth:kindth:label
th:langth:listth:longdesc
th:lowth:manifestth:marginheight
th:marginwidthth:maxth:maxlength
th:mediath:methodth:min
th:nameth:onabortth:onafterprint
th:onbeforeprintth:onbeforeunloadth:onblur
th:oncanplayth:oncanplaythroughth:onchange
th:onclickth:oncontextmenuth:ondblclick
th:ondragth:ondragendth:ondragenter
th:ondragleaveth:ondragoverth:ondragstart
th:ondropth:ondurationchangeth:onemptied
th:onendedth:onerrorth:onfocus
th:onformchangeth:onforminputth:onhashchange
th:oninputth:oninvalidth:onkeydown
th:onkeypressth:onkeyupth:onload
th:onloadeddatath:onloadedmetadatath:onloadstart
th:onmessageth:onmousedownth:onmousemove
th:onmouseoutth:onmouseoverth:onmouseup
th:onmousewheelth:onofflineth:ononline
th:onpauseth:onplayth:onplaying
th:onpopstateth:onprogressth:onratechange
th:onreadystatechangeth:onredoth:onreset
th:onresizeth:onscrollth:onseeked
th:onseekingth:onselectth:onshow
th:onstalledth:onstorageth:onsubmit
th:onsuspendth:ontimeupdateth:onundo
th:onunloadth:onvolumechangeth:onwaiting
th:optimumth:patternth:placeholder
th:posterth:preloadth:radiogroup
th:relth:revth:rows
th:rowspanth:rulesth:sandbox
th:schemeth:scopeth:scrolling
th:sizeth:sizesth:span
th:spellcheckth:srcth:srclang
th:standbyth:startth:step
th:styleth:summaryth:tabindex
th:targetth:titleth:type
th:usemapth:valueth:valuetype
th:vspaceth:widthth:wrap
th:xmlbaseth:xmllangth:xmlspace

Inline

How to use inline operations, we can enable inline operations by declaring th:inline="text" in the parent tag. Of course, if you want to use the entire page, you can declare it directly on the body. The specific usage is shown in the following code.

Template page:

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

The results are as follows:

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

This operation is equivalent to using th:text.

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

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

Disable inline operations

We can 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> Copy code

Results page:

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

JavaScript inlining

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. The specific usage is shown in the following code:
template page:

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

Results page:

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

CSS inline

We can enable the use of inline operation in css by declaring th:inline="css" on the style tag. The specific operation method is as follows:

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

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

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

Results page:

<style th:inline= "css" > .main_elems { text-align: center; } </style> Copy code

Template layout

Define the reference fragment code

SpringBoot2.0 uses the template template layout to first introduce the thymeleaf-layout-dialect dependency of thymeleaf

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

Define the footer.html page This page is our quoted fragment 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> Copy code

We can define reference fragments through th:fragment, which can then be referenced on other pages. Define the 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> Copy code

Introduce the fragment defined in footer.html through th:insert and ~{...} fragment reference expressions, and define the controller that accesses the index page

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

Results page:

<div> <div> 2011 The Good Thymes Virtual Grocery </div> </div> Copy code

As the following code, the two ways of writing are consistent. If you think ~{footer::copy} is more troublesome, you can use the abbreviation footer::copy.

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

Declare fragments by id attribute

We can define the reference fragment through th:fragment, but we can also refer to the fragment by declaring the id attribute on the reference fragment code. The specific operation is as follows: Define the 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> Copy code

The template page that quotes the quoted fragment: 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> Copy code

Results page:

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

The results of footer :: #copy-section and ~{footer :: #copy-section} are the same.

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

  • th:insert is the simplest: it will display the content of tags and quote fragments that use th:insert
  • th:replace inserts the tag and content of the quoted fragment
  • th:include is similar to th:insert, only the content of this fragment is inserted.

th:insert

java code:

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

Declare the 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> Copy code

Quote 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> Copy code
#th:insert Result: <div> <footer> 2011 The Good Thymes Virtual Grocery </footer> </div> #th:replaceResult: <footer> 2011 The Good Thymes Virtual Grocery </footer> #th:include results: <div> 2011 The Good Thymes Virtual Grocery </div> Copy code

Reference fragment with parameters

Define the footer.html of the reference fragment code template page

<!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> Copy code

The template page that quotes the quoted fragment: 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> Copy code

Results page:

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

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

Delete template fragment

For our convenience, we need to add some simulation data by directly viewing the following page productList.html (mainly for viewing 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> Copy code

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

<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> Copy code

Thymeleaf provides us with 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> Copy code

After we declare th:remove="all" on the simulated data, we can access our previous simulated data through URL

What does this value in the all attribute mean? th:remove can be expressed in five different ways according to its value:

  • all: Delete the include tag and all its subtags.
  • body: Do not delete the include tag, but delete all its sub-tags.
  • tag: Delete the containing tag, but not delete its subitems.
  • all-but-first: Delete all the sub-items that contain the mark except the first one.
  • none: Nothing. This value is useful for dynamic evaluation. When we know the meaning of no attribute, we can declare it once, without having to define multiple th:remove="all"

Predefined tool objects

dates

Process date data generation, conversion, and obtain the specific number of days and years of the date.
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" ; } Copy code

format operation

java code:

#Code One Date date = new Date(); #Code Three Date[] datesArray = new Date[2]; datesArray[0] = date; datesArray[1] = date2; #Code Four List<Date> datesList = new ArrayList<Date>(); datesList.add(date); datesList.add(date2); model.addAttribute( "datesList" ,datesList); Copy code

Template page:

#Template one <span th:text= " ${#dates.format(date)} " >4564546</span> #Template two <span th:text= " ${#dates.format(date,'dd/MMM/yyyy HH:mm')} " >4564546</span> #Template three <p th:text= " ${#dates.format(datesArray,'yyyy-MM-dd HH:mm')} " ></p> Template # four <P TH: text = " $ {# dates.listFormat (datesList, 'dd/MMM/YYYY HH: mm')} " > </P> copy the code

Results page:

#Result One <span>January 30, 2020 at 10:03:24 AM</span> Result two <span>30/January/2020 10:03 </span> #Result Three <p>2019-05-30 10:03</p> #Result Four <p>[30/May/2019 10:03, 30/May/2018 00:00]</p> Copy code

Get date attribute operation

java code:

#Code One Date date = new Date(); Copy code

Template page:

#Template One <p th:text= " ${#dates.day(date)} " ></p> #Template two <p th:text= " ${#dates.month(date)} " ></p> #Template three <p th:text= " ${#dates.monthName(date)} " ></p> #Template Four <p th:text= " ${#dates.monthNameShort(date)} " ></p> #Template Five <p th:text= " ${#dates.year(date)} " ></p> #Template six <p th:text= " ${#dates.dayOfWeek(date)} " ></p> #Template Seven <p th:text= " ${#dates.dayOfWeekName(date)} " ></p> #Template eight <p th:text= " ${#dates.dayOfWeekNameShort(date)} " ></p> #Template Nine <p th:text= " ${#dates.hour(date)} " ></p> #Template ten <p th:text= " ${#dates.minute(date)} " ></p> #Template eleven <p th:text= " ${#dates.second(date)} " ></p> #Template twelve <p th:text= " ${#dates.millisecond(date)} " ></p> Copy code

Results page:

#Result One <p>30</p> # <p>5</p> # <p> </p> # <p> </p> # <p>2019</p> # <p>5</p> # <p> </p> # <p> </p> # <p>10</p> # <p>10</p> # <p>45</p> # <p>853</p>

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

# <p>Thu May 30 10:15:55 CST 2019</p> # <p>2019 5 30 10 15 55 </p> # <p>Thu May 30 00:00:00 CST 2019</p> # <p>Fri May 31 10:18:00 CST 2019</p> # <p>Thu May 30 10:18:34 CST 2019</p> # <p>Thu May 30 00:00:00 CST 2019</p>

numbers

:

  • 0 formatInteger
  • formatInteger
  • formatDecimal
  • formatPercent
  • sequence
@RequestMapping("/numbers") public String numbers(Model model) throws ParseException{ return "/course/numbers"; }

0

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

<p>0123</p> <p>123</p> <p>123</p>

Java

@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"; }

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

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

<p th:text="${#numbers.formatInteger('1000',2,'POINT')}"></p> <p th:text="${#numbers.formatInteger('1000',6,'POINT')}"></p> <p th:text="${#numbers.formatInteger('1000',7,'POINT')}"></p> <p th:text="${#numbers.formatInteger('1000',2,'COMMA')}"></p> <p th:text="${#numbers.formatInteger('1000',2,'WHITESPACE')}"></p> <p th:text="${#numbers.formatInteger('1000',2,'NONE')}"></p> <p th:text="${#numbers.formatInteger('1000',2,'DEFAULT')}"></p>

<p>1.000</p> <p>001.000</p> <p>0.001.000</p> <p>1,000</p> <p>1 000</p> <p>1000</p> <p>1,000</p>

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

<p>010.12</p> <p>01.000,12</p>

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

<p> 1,000.00</p>

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

<p>20.0000%</p> <p>020.00%</p>

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

<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> <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> <div><p>0</p></div> <div><p>2</p></div> <div><p>4</p></div>

strings

String :

  • toString
  • isEmpty
  • defaultString
  • contains + containsIgnoreCase
  • startsWith endsWith
  • substring substringAfter
  • replace
  • prepend append
  • toUpperCase toLowerCase
  • arrayJoin arraySplit
  • trim
  • abbreviate
  • concat

java

@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); } Object object = "123";

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

<p>123</p>

toString

Java

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

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

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

isEmpty

Java

String name = null;

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

<p>true</p>

Java

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

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

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

Java

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

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

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

defaultString

Java

String name = null;

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

<p> null</p>

Java

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

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

<p>[abc, null]</p>

contains

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

<p>true</p> <p>true</p>

startsWith endsWith

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

<p>true</p> <p>true</p>

indexOf

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

<p>3</p>

substring

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

<p>ef</p>

replace

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

<p>lerabce</p>

prepend

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

<p>012abc</p>

append

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

<p>abc456</p>

toUpperCase

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

<p>ABC</p>

toLowerCase

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

<p>abc</p>

length

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

<p>3</p>

trim

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

<p>abc</p>

abbreviate

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

<p>1234567...</p>

#objects

Object obj nullSafe
java

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

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

<p> null</p>

#bools

ture false

  • 1 ture , 0 false;
  • on true, off false;
  • true true, "false" false;

isTrue

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

<p>true</p> <p>false</p> <p>true</p> <p>false</p> <p>true</p> <p>false</p> <p>true</p> <p>false</p>

#arrays

  • toStringArray toIntegerArray
  • length
  • isEmpty
  • contains
  • containsAll
  • toStringArray Object containsAll +

toStringArray

java

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

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

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

length

java

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

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

<p>3</p>

isEmpty

java

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

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

<p>false</p>

contains

java

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

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

<p>true</p>

containsAll

java

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

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

<p>true</p>

#lists

list

  • (size)
  • list (isEmpty)
  • list (contains,containsAll)
  • list (sort)
    java
@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);

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

<p>3</p>

java :

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

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

<p>false</p>

java :

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

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

<p>true</p>

java :

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);

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

<p>true</p>

java :

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

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

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

#sets

set

  • Set(toSet)
  • (size)
  • set (isEmpty)
  • set (contains,containsAll)

size

java

@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);

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

<p>3</p>

isEmpty

java

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

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

<p>false</p>

contains

java

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

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

<p>true</p>

containsAll

java

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);

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

<p>true</p>

sort

java

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

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

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

#maps

map

  • (size)
  • map (isEmpty)
  • (containsKey,containsAllKeys,containsValue)

java

@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);

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

<p>3</p>

java

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

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

<p>false</p>

java

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

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

<p>true</p>

java

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);

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

<p>true</p>

java

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

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

<p>true</p>

java

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);

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

<p>true</p>

#aggregates

  • (sum)
  • (avg)

java

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

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

<p>10</p>

java

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

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

<p>10</p>

java

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

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

<p>2.5</p>

java

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

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

<p>2.5</p>

Thymeleaf Thymeleaf