CodeGym /Courses /Module 5. Spring /Template Engines in Spring MVC: Thymeleaf

Template Engines in Spring MVC: Thymeleaf

Module 5. Spring
Level 7 , Lesson 6
Available

Thymeleaf is a modern Java template engine that gives you a convenient and flexible way to create dynamic HTML pages. It integrates with Spring MVC and supports dual-mode rendering: HTML files can be used as static templates (for example, for frontend testing) and as server-side dynamically generated pages.

*The name "Thymeleaf" comes from the word *thyme (thyme) and carries the idea of "lightness and refinement" into templates.

Thymeleaf — a smart helper in web development

You know why devs love Thymeleaf? It makes HTML come alive and dynamic. Imagine: you write plain HTML and just add special attributes — that's the whole trick. Even if your server is down, the browser will still render your HTML without breaking.

Also, Thymeleaf works great for any project. Whether you're building a tiny page or a big portal, it fits. And yeah, it plays nicely with Spring out of the box!

Want to get how it works? It's kinda like building a game. You have an HTML template — that's the game's skeleton. Data are the game assets. Thymeleaf takes the skeleton and brings it to life, like a game engine. It places data where it belongs, adds touches, and turns plain markup into a full dynamic page.


Adding Thymeleaf to a Spring MVC project

Maven dependencies. First, you need to add Thymeleaf to your project. Put the following dependency into pom.xml:


<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

If you're using Gradle, add this line to build.gradle:


implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

Project structure. After adding Thymeleaf, you'll have a folder for templates. By default it's:


src/main/resources/templates

All your HTML templates should live in that folder. Spring Boot will automatically "see" them and load them.


Thymeleaf syntax basics

Extending HTML with attributes. Thymeleaf uses its own attributes that start with th:. For example:

  • th:text — for rendering text.
  • th:href — for links.
  • th:each — for loops.
  • th:if/th:unless — for conditions.

A simple example


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <title>Hello, Thymeleaf!</title>
</head>
<body>
  <h1>Welcome, <span th:text="${username}"></span>!</h1>
</body>
</html>

Here th:text="${username}" will replace the content of the span with the value of the username variable passed from the controller.


Passing data from the controller

Let's create a simple controller that sends data to a template.


@Controller
public class WelcomeController {

    @GetMapping("/")
    public String welcome(Model model) {
        model.addAttribute("username", "Junior Programmer");
        return "welcome"; // points to the welcome.html template
    }
}

Note:

  • We use the Model object to pass data to the template.
  • The returned value return "welcome"; points to the welcome.html file inside the templates folder.

Example HTML template (welcome.html)


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <title>Welcome</title>
</head>
<body>
  <h1>Hello, <span th:text="${username}"></span>!</h1>
</body>
</html>

If you open this in a browser, you'll see:


Hello, Junior Programmer!

Dynamic tables with Thymeleaf

Let's do something a bit more advanced. For example, render a list of students in a table.

Controller


@Controller
public class StudentController {

    @GetMapping("/students")
    public String listStudents(Model model) {
        List<String> students = List.of("Anna", "Ivan", "Maria", "Sergey");
        model.addAttribute("students", students);
        return "students"; // template students.html
    }
}

We use the Java 9+ method List.of(...) to keep it simple.

Template (students.html)


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <title>Students List</title>
</head>
<body>
  <h1>Students List</h1>
  <table border="1">
    <thead>
    <tr>
      <th>Name</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="student : ${students}">
      <td th:text="${student}"></td>
    </tr>
    </tbody>
  </table>
</body>
</html>

Here:

  • th:each="student : ${students}" — loops over the students collection.
  • Inside the loop we render the student's name with th:text="${student}".

Result in the browser:


Students List
-------------------
Name
Anna
Ivan
Maria
Sergey

Conditions in Thymeleaf

Sometimes you need to show or hide elements based on conditions.

Example using th:if and th:unless


<p th:if="${isAdmin}">Welcome, administrator!</p>
<p th:unless="${isAdmin}">Welcome, user!</p>

In the controller:


model.addAttribute("isAdmin", true);

Result. If isAdmin = true, you'll see:


Welcome, administrator!

Creating hyperlinks

Thymeleaf makes it easy to build links using path expressions.

Example


<a th:href="@{/students}">Students List</a>

Output:


<a href="/students">Students List</a>

Using @{} also works with dynamic parameters:


<a th:href="@{/student/{id}(id=${studentId})}">View student</a>

Integrating forms with Thymeleaf

Thymeleaf supports working with HTML forms. This is especially handy for collecting user input.

Controller example


@Controller
public class FormController {

    @GetMapping("/form")
    public String showForm(Model model) {
        model.addAttribute("student", new Student());
        return "form";
    }

    @PostMapping("/form")
    public String processForm(@ModelAttribute Student student) {
        System.out.println("Received student: " + student);
        return "form-success";
    }
}

Form template (form.html)


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <title>Form</title>
</head>
<body>
  <form action="#" th:action="@{/form}" th:object="${student}" method="post">
    Name: <input type="text" th:field="*{name}"><br>
    Age: <input type="number" th:field="*{age}"><br>
    <button type="submit">Submit</button>
  </form>
</body>
</html>
We use th:action and th:field for automatic binding to the model via the student object.

Handy tips and common mistakes

Most mistakes when using Thymeleaf come from:

  1. Missing dependencies. Check that spring-boot-starter-thymeleaf is included.
  2. Wrong folder structure. Make sure your HTML templates are in resources/templates.
  3. Thymeleaf syntax errors. Verify your th:* attributes are spelled correctly.

For deeper learning, check out the official Thymeleaf documentation.

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION