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.

  1. Add thymeleaf-spring dependency to your dependencies

     <dependency>
          <groupId>org.thymeleaf</groupId>
          <artifactId>thymeleaf-spring4</artifactId>
          <version>2.1.4.RELEASE</version>
     </dependency>
    
  2. 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.


Expressions

Thymeleaf works based on many expressions - it has different expression syntax other than the traditional ${variablename.propertyname} syntax, namely:

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