ミルラク

Thymeleafでフラグメント式th:fragmentを使用する

更新日: 2024-02-27

当サイトはアフィリエイト広告を利用しています。

Thymeleafを書籍で学びたい方やThymeleafと一緒にSpringも習得したい方におすすめな書籍です。
Springについての書籍ですが、Thymeleafの基本構文や他システムとの連携など30ページほど取り上げられています。
ThymeleafとSpringは親和性の高い技術なので、これを機にSpringを学んでみるのはいかがでしょうか?

実行環境

実行環境がない方は、こちらの記事を参考にしてください。

項目バージョン
OSmacOS Catalina
JDKOracle JDK@8
Thymeleaf3.1

Thymeleafでフラグメント式th:fragmentを使用する

ヘッダーやフッター, メニューなどのテンプレートを共通化したい場合、Thymeleafでは「フラグメント」を定義してインクルードします。
フラグメントは th:fragment="フラグメント名" または id 属性で定義し、th:insert または th:replace でインクルードします。

th:fragment

th:fragment = "フラグメント名" でフラグメントを定義することができます。
定義したタグおよびタグ内の要素がフラグメントとして扱われます。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head th:fragment="head">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>ミルラク Thymeleaf コードサンプル</title>
  <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>👀</text></svg>">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
  <link th:href="@{/css/style.css}" rel="stylesheet" />
</head>
</html>

th:insert

th:insert="~{フラグメントを定義したテンプレートファイルのパス :: フラグメント名}"インクルードする側のタグの中にフラグメントをインクルードします。パスは src/main/resources/templates から見た場所を指定します。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<th:block th:insert="~{fragments/head :: head}"></th:block>
<body>
  ・・・
</body>
</html>

th:replace

th:replace="~{フラグメントを定義したテンプレートファイルのパス :: フラグメント名}"インクルードする側のタグを上書きしてフラグメントをインクルードします。パスは src/main/resources/templates から見た場所を指定します。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<th:block th:replace="~{fragments/head :: head}"></th:block>
<body>
  ・・・
</body>
</html>

th:fragmentで引数を指定する

th:fragment = "フラグメント名(引数名)" で引数を指定することができます。引数は複数指定できます。

以下のコードサンプルでは、引数の menu が指定した値と一致する場合、th:classappend を使用して、要素に active というクラスを追加します。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<body>
  <aside th:fragment="sidebar(menu)">
    ・・・
      <ul class="nav nav-pills flex-column mb-auto">
        <li><a th:href="@{/}" class="nav-link text-light" th:classappend="${menu == 'home'} ? 'active'">ホーム</a></li>
        <li><a th:href="@{/option}" class="nav-link text-light" th:classappend="${menu == 'option'} ? 'active'">ラジオボタンとチェックボックス</a></li>
        ・・・
      </ul>
    ・・・
  </aside>
</body>
</html>

th:insert または th:replace="~{フラグメントを定義したテンプレートファイルのパス :: フラグメント名(引数の値)}" でインクルードします。パスは src/main/resources/templates から見た場所を指定します。

<aside th:insert="~{fragments/sidebar :: sidebar('home')}"></aside>
<aside th:replace="~{fragments/sidebar :: sidebar('option')}"></aside>

id属性を使用する

id = "フラグメント名" でフラグメントを定義することができます。
定義したタグおよびタグ内の要素がフラグメントとして扱われます。

<footer id="footer">
  <span>©︎ 2023-2024 ミルラク</span>
</footer>

th:insert または th:replace="~{フラグメントを定義したテンプレートファイルのパス :: #フラグメント名}" でインクルードします。パスは src/main/resources/templates から見た場所を指定します。

<th:block th:insert="~{fragments/footer :: #footer}"></th:block>
<th:block th:replace="~{fragments/footer :: #footer}"></th:block>

th:insertとth:replaceの違い

th:insert は、インクルードする側のタグの中にフラグメントをインクルードします。一方、th:replaceインクルードする側のタグを上書きしてフラグメントをインクルードします。

以下のコードサンプルの場合

<footer th:fragment="footer">
  <span>©︎ 2023-2024 ミルラク</span>
</footer>
<!-- th:insert -->
<div th:insert="~{fragments/footer :: footer}"></div>
<!-- th:replace -->
<div th:replace="~{fragments/footer :: footer}"></div>

ブラウザでの出力結果は以下のようになります。th:insertdiv タグの中にフラグメントをインクルードしますが、th:replacediv タグを削除してフラグメントをインクルードします。

<!-- th:insert -->
<div>
  <footer>
    <span>©︎ 2023-2024 ミルラク</span>
  </footer>
</div>
<!-- th:replace -->
<footer>
  <span>©︎ 2023-2024 ミルラク</span>
</footer>

お疲れさまでした

Thymeleafでフラグメント式th:fragmentを使用する方法を紹介しました。
少しでも参考になれば幸いです。