🏠ThymeleafThymeleaf Fragments in Spring Boot Application

Thymeleaf Fragments in Spring Boot Application

Spring Boot Thymeleaf

Thymeleaf fragments let you break down your templates into reusable layout elements. For example, Several pages may have different content but still have the same header and footer. In these cases, Writing these into a separate template file and reusing it is not a bad idea.

Fragments in Action

Let’s take this snippet from a hypothetical home page.

<body class="container"> <nav class="navbar bg-dark navbar-dark navbar-expand-lg"> <a class="navbar-brand" href="#">Logo</a> <div class="navbar-nav w-100 ml-auto" th:each="menu : ${menus}"> <a class="nav-link" th:href="${menu.url}" th:text="${menu.label}"></a> </div> </nav> .... .... Some content of the home page .... </body>
Code language: HTML, XML (xml)

Here, The navbar logic would never change for different thymeleaf view. In these cases, we can define the navbar HTML into a separate fragment and import it everywhere as we want it. Let’s split our template.

First, create a thymeleaf fragment file fragments/navbar.html under the templates directory.

<nav class="navbar bg-dark navbar-dark navbar-expand-lg"> <a class="navbar-brand" href="#">Logo</a> <div class="navbar-nav w-100 ml-auto" th:each="menu : ${menus}"> <a class="nav-link" th:href="${menu.url}" th:text="${menu.label}"></a> </div> </nav>
Code language: HTML, XML (xml)

Now, you can include this fragment into the home.html as shown below.

<body class="container"> <div th:replace="fragments/navbar"></div> .... .... Some content of the home page .... </body>
Code language: HTML, XML (xml)

Ways to include thymeleaf fragments

We can include other fragments into a template in two different ways. Let’s find about each one of them.

th:insert Directive

If you want the fragment to be wrapped around by a parent tag, you should use th:insert. Here is the syntax for this approach.

<div th:insert="fragments/navbar" id="this-will-be-retained">This content will be gone</div>
Code language: HTML, XML (xml)

The above snippet will result in a div containing the content of the navbar.html as shown below.

<div id="this-will-be-retained"> <nav class="navbar bg-dark navbar-dark navbar-expand-lg"> <a class="navbar-brand" href="#">Logo</a> <div class="navbar-nav"> <a class="nav-link" href="/">Home</a> </div> <div class="navbar-nav"> <a class="nav-link" href="/about">About us</a> </div> <div class="navbar-nav"> <a class="nav-link" href="/contact">Contact us</a> </div> </nav> </div>
Code language: HTML, XML (xml)

As you see, the div tag exists with its original attribute.

th:replace directive

You can specify where to include a fragment using the th:replace directive. This directive will remove the current element and fill it with the content of the fragment.

<div th:replace="fragments/navbar">This content will be gone</div>
Code language: HTML, XML (xml)

Here the <div> element itself will be replaced by the content of navbar.html. The resultant code would look like this.

<nav class="navbar bg-dark navbar-dark navbar-expand-lg"> <a class="navbar-brand" href="#">Logo</a> <div class="navbar-nav"> <a class="nav-link" href="/">Home</a> </div> <div class="navbar-nav"> <a class="nav-link" href="/about">About us</a> </div> <div class="navbar-nav"> <a class="nav-link" href="/contact">Contact us</a> </div> </nav>
Code language: HTML, XML (xml)

Points to note about thymeleaf fragments

  1. Fragments can be nested. That is, one fragment can contain another fragment. However, Make sure you don’t make a cyclic dependency. For example, the following scenario will lead to infinite recursion.
  2. In both th:insert and th:replace the content of the surrounding div is removed.
  3. Fragments are loaded from the relative path from the file it is invoked.
  4. There is also a th:include But this is just a deprecated version of th:insert.

Learn more about thymeleaf in the list of posts on that topic.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *