CodeGym /Courses /Module 5. Spring /Practice: integrating Thymeleaf to generate HTML pages

Practice: integrating Thymeleaf to generate HTML pages

Module 5. Spring
Level 7 , Lesson 7
Available

In this lecture we'll focus on practical use of Thymeleaf in a Spring MVC app. We'll build dynamic web pages with Thymeleaf and learn how to generate HTML pages with data coming from our controller. Get ready — today there's going to be a lot of code, a bit of magic, and something about how the web server does its "tricks" turning requests into pretty pages.


Adding Thymeleaf to a Spring MVC project

To start using Thymeleaf, you need to add the appropriate dependency to your project. We assume you're using Maven. If your project uses Gradle, add the equivalent dependency.

Adding Thymeleaf to pom.xml


<dependencies>
  <!-- Spring Boot Starter for Thymeleaf -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    <version>3.1.0</version> <!-- Use the current version -->
  </dependency>
</dependencies>

After that Maven will download the required libraries and your project will be ready to work with Thymeleaf.


Thymeleaf configuration

Spring Boot auto-configures Thymeleaf to work with templates placed in the resources/templates folder. If you create a project on Spring Framework without Spring Boot, you'll need to set up template processing configuration yourself.

For simplicity we're using Spring Boot, so the setup is ready "out of the box".


First Thymeleaf app

Step 1: Create the controller

Let's start by creating a controller. For example, we want to display a list of students on a web page.


package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Arrays;
import java.util.List;

@Controller
public class StudentController {

    @GetMapping("/students")
    public String getStudents(Model model) {
        // Create a list of students
        List<String> students = Arrays.asList("Ivan Ivanov", "Maria Petrova", "Alexey Sidorov");

        // Add the list to the model
        model.addAttribute("students", students);

        // Return the template name (students.html)
        return "students";
    }
}

What happens here:

  1. We create an endpoint /students that handles GET requests.
  2. Inside the method a list of students is created and passed to the Model object. This object is used to send data from the controller to the template.
  3. The method returns the template filename (students.html). Spring MVC automatically looks for the template in resources/templates.

Step 2: Create the students.html template

Create a file students.html in resources/templates. It will contain HTML with some Thymeleaf bits.


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <title>Student List</title>
</head>
<body>
  <h1>Student List</h1>
  <ul>
    <!-- Thymeleaf expression to display data -->
    <li th:each="student : ${students}" th:text="${student}"></li>
  </ul>
</body>
</html>

Explanation:

  1. xmlns:th="http://www.thymeleaf.org" - the namespace declaration for Thymeleaf.
  2. th:each="student : ${students}" - a loop where we iterate over each student from the students list.
  3. th:text="${student}" - outputs the current student into the HTML.

Step 3: Run the app

Run the Spring Boot app. Open http://localhost:8080/students in your browser. You'll see a dynamically generated page with the student list.


Working with dynamic data

Thymeleaf supports many expressions for working with data. Here are a few examples:

Thymeleaf expressions

Syntax Description
${} An expression to access model variables (e.g. ${student} to access a student object)
th:text Sets the text content of an element (e.g. <p> -> <p>Text</p>)
th:href Sets the href attribute of a link (e.g. <a> -> <a href="URL">)
th:if, th:unless Conditional rendering of HTML (e.g. th:if="${isLoggedIn}")

Template with dynamic links

Here's an example where we add links for each student:


<ul>
  <li th:each="student, iterStat : ${students}">
    <a th:href="@{'/students/' + ${iterStat.index}}" th:text="${student}"></a>
  </li>
</ul>

Here iterStat.index is used to add the item's index into the link.


Practice: building a UI for entities

Now let's do server-side rendering for an entity that was previously added to our app.

Step 1: Create the Book entity


package com.example.demo.model;

public class Book {
    private String title;
    private String author;

    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }
}

Step 2: Controller for books


package com.example.demo.controller;

import com.example.demo.model.Book;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;

@Controller
public class BookController {

    @GetMapping("/books")
    public String getBooks(Model model) {
        // List of books
        List<Book> books = List.of(
                new Book("War and Peace", "Leo Tolstoy"),
                new Book("Crime and Punishment", "Fyodor Dostoevsky"),
                new Book("The Master and Margarita", "Mikhail Bulgakov")
        );
        model.addAttribute("books", books);
        return "books";
    }
}

Step 3: Template for books books.html


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <title>Book List</title>
</head>
<body>
  <h1>Book List</h1>
  <table>
    <tr>
      <th>Title</th>
      <th>Author</th>
    </tr>
    <tr th:each="book : ${books}">
      <td th:text="${book.title}"></td>
      <td th:text="${book.author}"></td>
    </tr>
  </table>
</body>
</html>

Tips and common mistakes

  1. Make sure the template name is correct. When a string is returned from the controller it must match the filename in the templates folder. If the file is missing you'll get a Template not found error.
  2. Thymeleaf namespace. Don't forget to add xmlns:th="http://www.thymeleaf.org" to the root HTML element. Without it Thymeleaf directives won't work.
  3. Working with collections. If you pass a collection to the model, make sure it's not null. Otherwise you'll get an error while iterating.

Now you've got all the tools to create server-rendered HTML pages with Thymeleaf. Use this knowledge to improve your app! 🎉

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