Most web sites will have some form of consistency in their structure - often realised as a header and footer. In this tutorial, we will introduce that structure.
It is good practice to make it obvious what files reside in which folders.
Create a folder called fragments
under /main/resources/templates
.
In the fragments
folder, create a file called header.html
and enter this content.
In header.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
rel="stylesheet" th:fragment="bootstrap-css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light" th:fragment="header">
<div class="container">
<a class="navbar-brand" href="/">
<span><img alt="Charity Giving Logo" src="/images/cg-logo.jpg"/>
</span>
</a>
</div>
</nav>
</body>
</html>
Note that this is a full HTML page and that the head
tag contains elements to include Bootstrap. There is then a nav
tag within the body
tag.
Pay specific attention to the th:fragment
attributes.
These identify the elements that should be treated as fragments.
There are two in the header.
Do the same for a footer with this content.
In footer.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
<div>
<script crossorigin="anonymous" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
th:fragment="bootstrap-js"></script>
</div>
</body>
</html>
Note that this contains the script
tag to include the Bootstrap JavaScript and that that element has the th:fragment
attribute on it.
We can now amend the index.html
page to include the fragments.
In index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Welcome to Charity Giving</title>
<link th:replace="fragments/header :: bootstrap-css"></link>
</head>
<body>
<div class="container">
<div th:replace="fragments/header :: header"/>
<div>
<span>Welcome to Charity Giving. Today is </span><span th:text="${today}"></span>
</div>
<div>
<a href="charities">View our charities</a>
</div>
</div>
<div th:replace="fragments/footer :: bootstrap-js"></div>
</body>
</html>
In the head
element, we have this:
<link th:replace="fragments/header :: bootstrap-css"></link>
The th:replace
attribute tells Thymeleaf to replace this link
element with what it finds in fragment called "bootstrap-css" within the fragments file (located at fragments/header) - there is no need for the ‘.html' suffix.
This is repeated for the footer as well.
This is the simplest way of using Thymeleaf fragments. There is another method that can produce a neater design but requires more work. There are also additional Thymeleaf attributes for other scenarios.