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.
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.
In both th:insert and th:replace the content of the surrounding div is removed.
Fragments are loaded from the relative path from the file it is invoked.
There is also a th:include But this is just a deprecated version of th:insert.
1- Fragment là gì?
Một Fragment (Mảnh) là một phần trong một Template. Thymeleaf cho phép bạn nhập khẩu các fragment của Template này vào một Template khác. Có rất nhiều cách để bạn xác định một Fragment. Chẳng hạn:
Lựa chọn tất cả các thẻ (tag) có thuộc tính (attribute) th:fragment="search-fragment".
Lựa chọn thẻ theo ID.
Lựa chọn tất cả các thẻ theo Css-class.
....
Điều quan trọng khi bạn muốn nhập khẩu một Fragment của một Template nào đó, bạn phải mô tả được vị trí của nó.Cú pháp để mô tả vị trí của một Fragment thuộc một Template nào đó:
~{/path-to-template/template-name :: selector}
Nếu bạn muốn mô tả vị trí của Fragment thuộc Template hiện tại, thì có thể sử dụng một cú pháp ngắn gọn hơn:
~{:: selector}
~{this :: selector}
~{templatename: fragmentname} (th:fragment)Lựa chọn fragment theo tên.~{templatename: tagname} (Tag Name)Lựa chọn fragment theo tên của thẻ.Lựa chọn các thẻ con của một thẻ. Chẳng hạn, lựa chọn tất cả các thẻ <script> nằm trong thẻ <header>:~{templatename: #id} (ID)Lựa chọn fragment theo giá trị của thuộc tính (attribute) ID của thẻ.~{templatename: .classname},~{templatename: tagname.classname} (Css Class)Lựa chọn fragment theo Css Class:~{templatename} (Everything)Lựa chọn tất cả trong Template:Other...Các ví dụ khác:
Tính năng cho phép nhập khẩu các fragment từ một Template này vào một Template khác thực sự rất tuyệt vời, nó giúp cho việc thiết kế giao diện của website trở lên dễ dàng hơn. Hãy xem một ví dụ dưới đây:Trong ví dụ này, tập tin my-template.html chứa nhiều fragment, mà các Template khác có thể nhập khẩu để sử dụng./fragments/my-template.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>My Template</title>
<link rel="stylesheet" type="text/css" th:href="@{/main.css}"/>
<link rel="stylesheet" type="text/css" th:href="@{/secondary.css}"/>
<script type="text/javascript" th:src="@{/main.js}"></script>
<script type="text/javascript" th:src="@{/secondary.js}"></script>
</head>
<body>
<!-- Script in body -->
<script type="text/javascript" th:src="@{/script-in-body.js}"></script>
<ul th:fragment="my-fragment1">
<li><a th:href="@{/}">Home</a></li>
<li><a th:href="@{/products}">Products</a></li>
<li><a th:href="@{/about}">About</a></li>
</ul>
<ul th:fragment="my-fragment2">
<li><a th:href="@{/admin/products}">Product Management</a></li>
<li><a th:href="@{/admin/orders}">Order Management</a></li>
</ul>
<div id = "my-id1">
Element DIV with id = 'my-id1'
</div>
<aside>
<div>This is a sidebar</div>
</aside>
<p class="my-class">Element P with class (my-class)</p>
<p>Element P without class</p>
<p class="my-class">Element P with class (my-class)</p>
</body>
</html>
Tập tin my-page.html là một Template, nó nhập khẩu một vài fragment của my-template.html:my-page.html (Template)
Một fragment sẽ giống như một hàm (function) hơn nếu nó có thêm các tham số, và thật may mắn Thymeleaf hỗ trợ điều này.Tham số tường minh:Nếu bạn khai báo một fragment và liệt kê một cách tường minh danh sách các tham số của nó. Các tham số này sẽ là các tham số bắt buộc. Chẳng hạn như ví dụ dưới đây:
Thuộc tính (attribute) th:assert giúp bạn đánh giá một biểu thức, hoặc nhiều biểu thức (Các biểu thức cách nhau bởi dấu phẩy). Nếu tất cả các biểu thức được đánh giá là true (đúng) sẽ không có vấn đề gì xẩy ra, nếu có 1 biểu thức bị đánh giá là false (sai) một ngoại lệ sẽ được ném ra.
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.