Thymeleaf cheat sheet
This is a cheat sheet to summarize all the main Thymeleaf features and how to use them to kickstart you with Thymeleaf.
What is Thymeleaf
Thymeleaf is an engine that builds dynamic pages from templates that are written in XHTML with the help of some special attributes, so it is a template engine.
A template engine in Java is an engine that parses XHTML pages which contain special tags and attributes or syntax. Those attributes will then use some variables to build the web page, and are bound to fields of Java beans on the server side. The engine will resolve those variables in the attributes to their actual values, then process the page according to those values and build a normal HTML page.
For example, the templating engine will resolve the values of the list of students which was passed through the controller, and then use those values to replace the attributes and dummy text with actual data from the fetched list.
Thymeleaf is an in-memory template engine, so it does all of its processing in memory which makes it quite fast. It builds a DOM that maps to the HTML of the page and binds the values to those fields which are displayed, and when the values from the server change the parsed fields and pages are updated accordingly. Its caching is also an in-memory caching system, which means that the cache will invalidate with every server restart.
Thymeleaf is a template engine that relies mostly on attributes, unlike common engines which rely on tags as in JSP or JSF. This makes it testable in the browser directly without requiring a server to parse the special HTML tags, which eases the work between designer and developer, as they can both test the same page.
How it works
Let’s consider this piece of code:
<p th:text="'Thymeleaf will display this'">text</p>
Here Thymeleaf will process the text inside the th:text
attribute, and replace the contents of the <p>
tag with it.
Thymeleaf works by replacing the contents of the tags that its attributes are defined on.
so the final in the browser output will be:
<p>Thymeleaf will display this</p>
Notice that the special attributes are now gone, as well as the text “text” which is now replace with the contents of the Thymeleaf attribute.
A more complicated example:
<tr th:each="prod : ${prods}">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<tr>
Here Thymeleaf will repeat the <tr>
with the list of products, this is defined by the attribute th:each
, it will also remove the dummy content in both the <td>
tags, and replace them with the content that is evaluated from th:text="${prod.name}"
and th:text="${prod.price}"
.
Thymeleaf Layout Dialect
This dialect adds JSF-like template hierarchy to the Thymeleaf Engine, which makes it possible that you have templates extending other templates and overriding fragments of those parent templates that we open for extension. This is useful when you have a common layout that you want to apply to all your pages and views, for example a footer or a sidebar or common CSS and JavaScript tags. To start, you need the dependency:
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>1.3.1</version>
</dependency>
Now you can add your common content in your parent layout page, and then define the part that you want extending templates to substitute with their custom content in a fragment, then in extending templates you use this parent template as your layout-decorator, then override the fragment with your custom content.
For example, say we have a main.html which contains a navbar, a sidebar, and a footer, and it has the middle part empty waiting for content to be inserted in it, it then defines this middle part as follows:
<div class="container">
<div layout:fragment="content" class="noborder">
</div>
</div>
Then in the overriding template, for example index.html, we use layout:decorator="main"
at the <html>
tag, where main is the parent template to be extended.
Then in index.html we do this to override the fragment content
<div layout:fragment="content">
<p th:text="${template}">Should not be displayed</p>
</div>
This will override the fragment’s content with the content in the div
tag.
For more information, please check this.
Spring Integration
Thymeleaf has a Spring integration project, that eases the integration of Spring MVC with Thymeleaf as a template.
-
Add
thymeleaf-spring
dependency to your dependencies<dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring4</artifactId> <version>2.1.4.RELEASE</version> </dependency>
-
Add this configuration to your Spring servlet configuration
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver"> <property name="prefix" value="/WEB-INF/templates/" /> <property name="suffix" value=".html" /> <property name="templateMode" value="HTML5" /> </bean> <bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine"> <property name="templateResolver" ref="templateResolver" /> <property name="additionalDialects"> <set> <bean class="nz.net.ultraq.thymeleaf.LayoutDialect" /> </set> </property> </bean> <bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver"> <property name="templateEngine" ref="templateEngine" /> </bean>
This configuration will make the Thymeleaf resolver the
ViewResolver
of Spring MVC, the<property name="templateMode" value="HTML5" />
is particulary important, as it sets the mode of which Thymeleaf should operate, we here specify the mode to be HTML5, which means that Thymeleaf should produce valid HTML5 HTML.
Attributes
Thymeleaf is an attribute based template engine - it processes attributes and their values to build its DOM tree.
-
th:text
: this attribute is responsible for displaying text that is evaluated from the expression inside it; it will process the expression and then display the text HTML-encoded. For example:<p th:text="#{home.welcome}">Welcome to our grocery store!</p>
th:utext
: Similar to previous attribute, but this one displays text unescaped. For more information check Using Texts.th:attr
: Takes an HTML attribute and sets its value dynamically. Example:<input type="submit" value="Subscribe me!" th:attr="value=#{subscribe.submit}"/>
Thevalue
attribute will be set to the value of#{subscribe.submit}
after processing, replacing the suppliedvalue="Subscribe me!"
th:value
,th:action
,th:href, th:onclick
…etc: Those attributes can be used as a shorthand of theth:attr
syntax, so the attributeth:action
is equivalent toth:attr="action="
.th:attrappend
: This will not replace the attribute value, but only append the value to it, example:th:attrappend="class=${' ' + cssStyle}"
. For more information check Setting Attribute Values.-
th:each
: This is the iteration attribute - it is analogous to Java’s for-each loop:for(Object o : list)
, but its syntax is<tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.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> </tr>
The
th:each="prod,iterStat : ${prods}"
is equivalent tofor(Product prod : prods)
and theiterStat
is the status variable of the iteration. It contains information about current iteration like its number, index, total count, etc. The iteration objectprod
can then be accessed in the context of the tag<th>
, meaning it will only exist within the tag that it’s been defined in, for more information check Iteration. th:if
: Evaluates the conditions specified in the attribute and if they are true, the tag is displayed; if not they are not displayed. Example :th:if="${user.admin}"
th:unless
: Is the opposite ofth:if
, it will display the tag if the value is false, soth:unless="${user.admin}"
is equal toth:if="${!(user.admin)}"
.-
th:switch
andth:case
: These attributes are used to create a switch statement,th:switch
will hold the variable to switch on, andth:case
will evaluate the case statements for this variable. Example:<div th:switch="${user.role}"> <p th:case="'admin'">User is an administrator</p> <p th:case="#{roles.manager}">User is a manager</p> <p th:case="*">User is some other thing</p> </div>
For more information check Conditional Evaluation.
Expressions
Thymeleaf works based on many expressions - it has different expression syntax other than the traditional ${variablename.propertyname}
syntax, namely:
#{message.in.proprties.file}
similar to the i18n resolver in JSF, this expression will look for the value provided in the localization properties files provided to the application. Example:<p th:text="#{brand.name}">Brand Name</p>
, when using Spring it will use theMessageSource
of Spring.${variable}
: This is the variables expression, if your expression should evaluate to a variable or you have a variable in yourmodel
as an attribute, you must use this expression to access it; other expressions are used for different purposes and may not function correctly with variables. Example:<span th:text="${today}">13 february 2011</span>
- Thymeleaf provides some predefined variables that can be accessed using the
${#variableName}
syntax and they are:#ctx
: the context object.#vars
: the context variables.#locale
: the context locale.#httpServletRequest
: (only in Web Contexts) theHttpServletRequest
object.#httpSession
: The session object of the current session#dates
: utility methods forjava.util.Date
objects: formatting, component extraction, etc.#calendars
: analogous to#dates
, but forjava.util.Calendar
objects.#numbers
: utility methods for formatting numeric objects.#strings
: utility methods for String objects : contains, startsWith, prepending /appending, etc.#objects
: utility methods for objects in general.#bools
: utility methods for boolean evaluation.#arrays
: utility methods for arrays.#lists
: utility methods for lists.#sets
: utility methods for sets.
Example:
<span th:text="${#locale.country}">
and
<span th:text="${#calendars.format(today,'dd MMMM yyyy')}">13 May 2011</span>
*{property}
: This is used the same way as the${variable}
but works on selected objects, i.e. objects which are set usingth:object
attribute. For example:
<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 will access properties on ${session.user}
object directly using the *{...}
syntax, like for *{firstName}
, this is equal to using ${session.user.firstName}
Note: The th:object
is defined only in the context of the tag it’s declared on, this means that it’s not available outside the context of that tag.
-
@{/link/path}
: This will create a link to the path specified relative to the deployment context, so if the application is deployed at context my-app, then the generated path will be /my-app/link/path.
To add get parameters use@{/link/path(param=value)}
which will generate /link/path?param=value
For Path variables use:@{/link/{pathVariable}/path(pathVariable=${variable})}
which will replace the {pathVariable} with the value from ${variable} - Literals: You can also write some normal literals instead of any expressions,
- “‘the literal string’”: You can write normal strings between two ’‘ single quotes.
- “3 + 2”: Normal numeric expressions
- “false”,”true” and “null”: are evaluted to normal
false
,true
andnull
expressions. - “singleWordToken”: tokens with single words do not need single quotes and can be written as they are.
${#fields}
: Spring MVC adds another predefined varable which is#fields
, it refers tospring-form
fields and their validation errors, mainly used for error validation.${@beanName.method()}
: Also Spring specific; a bean method call expression. This will call a method on a Spring bean calledbeanName
, which will look for the bean in the current Spring context and then execute this method.