thymeleaf of springboot

Keywords: Thymeleaf Session Fragment Spring

Introduction to thymeleaf

Simply put, Thymeleaf is a template engine similar to Velocity and FreeMarker, which can completely replace JSP. Compared with other template engines, it has the following three attractive features:

1.Thymeleaf can run in both network and non-network environments, that is, it can allow artists to view the static effect of pages in browsers, and also allow programmers to view the dynamic effect of pages with data in servers. This is because it supports HTML prototypes and then adds additional attributes to HTML tags to achieve template + data presentation. When browsers interpret html, undefined tag attributes are ignored, so the thymeleaf template can run statically; when data is returned to the page, the Thymeleaf tag will replace the static content dynamically and make the page display dynamically.

2.Thymeleaf's out-of-the-box features. It provides two dialects, standard and spring standard. It can directly apply template to achieve JSTL and OGNL expression effect, and avoid the trouble of setting template, JSTL and changing label every day. Developers can also extend and create custom dialects.

3.Thymeleaf provides spring standard dialect and an optional module integrated perfectly with Spring MVC, which can quickly realize form binding, attribute editor, internationalization and other functions.

Standard expression grammar

They fall into four categories:

1. Variable expression
2. Selection or asterisk expression
3. Word Internationalization Expressions
4.URL expression

Variable expression

Variable expressions are either OGNL expressions or Spring EL expressions (also called model attributes in Spring terminology). As follows: ${session.user.name}

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

<span th:text="${book.author.name}">

<li th:each="book : ${books}">

Select (asterisk) expressions

Selective expressions are very much like variable expressions, but 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 attribute:

<div th:object="${book}"> 

  ... 

  <span th:text="*{title}">...</span> 

  ... 

</div>

Word internationalization expression

Text internationalization expressions allow us to retrieve regional text information (. properties) from an external file, index Value with Key, and provide a set of parameters (optional).

#{main.title} 

#{message.entrycreated(${entryId})}
<table> 

  ... 

  <th th:text="#{header.address.city}">...</th> 

  <th th:text="#{header.address.country}">...</th> 

  ... 

</table>

URL expression

A URL expression refers to the addition of a useful context or callback information to a URL, a process often referred to as URL rewriting. @ {order/list}
The 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}">

Is there any difference between variable expression and asterisk expression?

There is no difference between the two without considering the context; asterisk grammar evaluation is expressed on the selected object, not the whole context.
What is the selected object? The value of the parent tag is 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>

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>

Of course, the dollar sign and asterisk grammar 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>

Grammar 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, some text, main,...

Text operations

  • String concatenation:+
  • Literal substitutions: | The name is ${name}|

Arithmetic operations

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

Boolean operations

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

Comparisons 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 these features can be combined and nested:

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

What are the commonly used th tags?

There are a lot of tags, but only the most commonly used ones are listed here. Because a tag can contain multiple th:x attributes, its priority order is: include, each, if/unless/switch/case, with, attr/attrprepend/attrappend, value/href, src, etc, text/utext, fragment, remove.

Several Commonly Used Methods

1. Assignment and String Mosaic

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

String splicing has another concise way of writing

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

2. Conditional Judgment If/Unless

Thymeleaf uses th:if and th:unless attributes to make conditional judgments. In the following example, the < a > tag is displayed only when the condition in th:if holds:

<a th:if="${myself=='yes'}" > </i> </a>

<a th:unless=${session.user != null} th:href="@{/login}" >Login</a>

th:unless, on the contrary, shows its content only if the condition in the expression is not valid.

You can also use the grammar (if)? (then): (else) to judge what is displayed.

3. for cycle

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

iterStat is called a state variable, and its attributes are:

  • index: index of the current iteration object (calculated from 0)
  • count: Index of the current iteration object (calculated from 1)
  • Size: The size of the iterated object
  • Curr: current iteration variable
  • Even/odd: Boolean value. Is the current loop even/odd (calculated from zero)?
  • First: Boolean value, is the current loop the first?
  • Last: Boolean value, is the current loop the last?

4,URL

URLs play an important role in Web application templates. It should be noted that Thymeleaf handles URLs through the grammar @{ } To deal with. If Thymeleaf is needed to render the URL, then be sure to use th:href, th:src and other attributes. Here's 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>

Setting background

<div th:style="'background:url(' + @{/<path-to-image>} + ');'"></div>

Change background based on attribute values

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

A few notes:

  • The last (orderId=${o.id}) of the URL in the example above indicates that the contents in parentheses are treated as URL parameters. This grammar avoids string splicing and greatly improves readability.
  • ]... } The orderId variable in Context can be accessed through {orderId} in the expression
  • @ The {order} is the relative path related to the Context. When rendering, the Context name of the current Web application is automatically added. Assuming the context name is app, the result should be / app/order.

5, inline js

Inline text: [[... ]] Inline text representation, when used, must be activated with th:inline= "text/javascript/none", th:inline can be used in the parent tag, or even as a body tag. Although inline text has less code than th:text, it is not conducive to prototype display.

<script th:inline="javascript">

/*<![CDATA[*/

...

var username = /*[[${sesion.user.name}]]*/ 'Sebastian';

var size = /*[[${size}]]*/ 0;

...

/*]]>*/

</script>

js additional code:

/*[+

var msg = 'This is a working application';

+]*/

js removes code:

/*[- */

var msg = 'This is a non-working template';

/* -]*/

6. Embedded variables

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

  • dates: The functional method class of java.util.Date.
  • calendars: Similar to # dates, for java.util.Calendar
  • Number: Functional Method Class for Formatting numbers
  • strings: Functional classes of string objects, contains,startWiths,prepending/appending, etc.
  • Objects: Functional class operations on objects.
  • bools: Functional method for evaluating Boolean values.
  • Arays: Functional class methods for arrays.
  • Lists: Functional class methods for lists
  • sets
  • maps

Here is a code to illustrate 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()}

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

Using thymeleaf layout

It's very convenient to use thymeleaf layout

Define code fragments

<footer th:fragment="copy">

© 2016

</footer>

Introduce anywhere on the page:

<body>

  <div th:include="footer :: copy"></div>

  <div th:replace="footer :: copy"></div>

 </body>

The HTML returned is as follows: th:include is different from th:replace. Include is only loading, replace is replacing.

<body>

   <div> © 2016 </div>

  <footer>© 2016 </footer>

</body>

Following is a common background page layout, which divides the whole page into header, tail, menu bar, hidden bar. Click on 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>

Any page that wants to use such layout values only needs to replace the content module seen in it.

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

  <body>

     <section layout:fragment="content">

   ...

You can also refer to the template when you refer to it.

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

Layout is the file address, if there is a folder, you can write fileName/layout:htmlhead
HTML head refers to defined code fragments such as th:fragment="copy"

Posted by Erestar on Tue, 07 May 2019 13:10:38 -0700