Introducing the Thymeleaf template engine


There’s a bunch of Java template engines, but one of them has been getting some momentum these days: Thymeleaf. Nice and powerful syntax, flexibility, vibrant community, and good integration with popular web technologies, these are all good reasons to discover this alternative to JSP. This article lists the core features of Thymeleaf and shows how to write and process an HTML template.

Thymeleaf in a nutshell

Thymeleaf is a Java template engine. It’s an open source project and is licensed under the Apache License 2.0. Here are the core features of Thymeleaf:

  • Simple and natural templating
  • Optimized for web environment but can work standalone
  • Advanced evaluation language (OGNL or Spring Expression Language)
  • Support for template logic (condition, iteration)
  • Full support for internationalization
  • Spring MVC and Spring Web Flow integration
  • Support for the composite view pattern (native with fragments, Tiles integration, usable with Sitemesh)
  • Sophisticated template caching support
  • Works with Dandelion-Datatables

Yes, that’s a lot of features! Keep reading to discover how to write and feed a Thymeleaf template with data…

Setup of the template engine

Thymeleaf infrastructure is quite simple: a TemplateResolver to load templates and a TemplateEngine to do the actual processing (merging templates with a given context). Here is the code for a standalone setup:

We’re going to load the templates from the root of the classpath. When we ask Thymeleaf to render a template called home, the resolver will add the html extension, because we set the suffix property. We’ll be then able to think in terms of logical names and won’t worry about the physical name of the file.

The template

Our template is a home.html file located at the root of the classpath (e.g. in the src/main/resources directory of the project if we follow Maven conventions). The first version of the template contains only the skeleton an HTML page:

Note the use of a Thymeleaf-specific doctype.

Processing of the template

There’s nothing dynamic in our template, but we can test our setup by adding the following code after the engine configuration:

The writer variable should then contain the output of the processed template, which is basically the static content of the file. Things that matter:

The processing needs a context. This object will typically contain variables we want to display in the view.

The template to render is called home. The resolver will be in charge of mapping this logical name with the physical location of the file. Remember we’re using a classpath-based resolver which adds an HTML extension to the template name.

OK, everything seems to work! See how Thymeleaf is lightweight. The template engine will be most of the time used in a web environment, but we can also easily use it in a standalone environment, like a JUnit test.

Labels and internationalization (i18n)

Thymeleaf’s default internationalization support is quite simple: drop a properties file beside your template and you’re done. Let’s create a in the same directory as our template:

And a file for the French version:

We modify our template to refer to this label:

That’s it, we unveiled how we insert dynamic content in Thymeleaf’s templates: by placing extra attributes in HTML elements:

The nested Hello is there just for a preview, Thymeleaf will replace it by the dynamic value during processing. Note the use of a Thymeleaf’s specific th:text attribute and the use of the #{key} syntax to refer to an entry of the property file.

If we execute the rendering program, we end up with the following output (if your locale is something else than French!):

What about the French version? We can specify the locale in the context:

And Thymeleaf uses the appropriate properties file:

So far, so good, let’s move on to the core topic: pushing objects in the context to render them in the view.

Variable substitution

Let’s imagine we want to display the current date in the view. We can feed the context with an already-formatted string:

And then refer to this variable in the template like the following:

Note the use of the ${variable} syntax this time (we used #{...} for i18n). We’re again relying on the th:text attribute to inject dynamic content. If we process the template again, the output contains the expected content:

Let’s see how to display a typical domain object.

Variable substitution with a Java bean

Displaying domain objects is a common use case of web applications. We can add a Contact object for display to the Thymeleaf context:

We hard-coded the domain object state, but it could be as well loaded from a database. Here’s how to display the firstname and lastname properties of the domain object:

As you can see, the content of ${...} in Thymeleaf can be a complex expression, not only the reference to variable. Thymeleaf uses OGNL for its default processing engine, opening a wide range of possibilities: operators, concatenation, etc.

Let’s see now an extra feature that can make the display of Java object shorter.

Less verbosity with the selection syntax

Thymeleaf allows to perform a selection on objects. Once an object has been selected, it’s available as some kind of first-level variable in the evaluation context. We can then refer to it using the *{...} syntax instead of the ${...} syntax.

In our template, we can select the contact object with the usual ${...} syntax and then refer to its properties with the *{...} syntax:

We end up with the exact same rendering, but the template code is more simple. Nice, isn’t it?


Another common use case of web applications is the display of data in tables: we load a list of Java objects from the database and display them in a HTML table. Imagine we feed our context with a List<Contact>:

The iterate over the list, we use the th:each attribute:

We end up with this output:


Note Thymeleaf added some rowspan and colspan attributes in accordance with the DTD for the selected XHTML 1.0 Strict standard. Thymeleaf wouldn’t generate them if we have told it to be compliant to HTML 5.

Before finishing our discovery of Thymeleaf, let’s play with conditional statements.

Conditional, “if” syntax

Imagine we don’t want to display an empty table if the list of contacts is empty, we can easily check the size of the list and choose to display the whole table o
nly if the list isn’t empty:


Note the use of the #lists utility objects to check whether the list is empty or not.


This article introduced the basic templating features of Thymeleaf. Thymeleaf is meant to be used in web applications, but its flexibility let us use it in a standalone environment. Thymeleaf doesn’t need a JSP compiler and can fetch templates from anywhere (file system, web context, classpath). You can even package your whole web application in a simple JAR, that’s a great step towards modularity! Thymeleaf has tons of features and we’ll see how to integrate it with Spring MVC in a subsequent post.

Source code

Partagez cet article.

A propos de l'auteur

6 commentaires

  1. Many thank’s Arnaud for your article. I didn’t know this template engine framework. The most popular Java template engine ar Freemarker and Velocity. So when I read your article, I told me why choosing thymeleaf instead of using Freemarker or Velocity? There are an answer at

    I think too tooling is very important for a language and it seems that it exists Eclipse plugin for thymeleaf at

    Very interesting project, thank’s to have shared it.

    Regards Angelo

  2. Thanks for this nice intro to a great tool !
    Thymeleaf is a good framework due to it’s simplicity, enforcing a clear separation of the “M” and the “V”
    Another approach can consist in sticking to a pure HTML template, then inject data and logic into it with a tool like Moulder-J (

  3. Arnaud Cogoluègnes on

    @Angelo: I’m glad you discovered this framework thanks to the post. Enjoy!
    @Daniel: thanks for the link on the Thymeleaf website! Keep up the good work!

Ajouter un commentaire