はじめに
こんにちは。
作ったアプリの課題を整理し、まずはUIの改善に取り組んでいます。
その中で、ヘッダーやサイドメニューなど共通部分を使い回す方法を学んだので内容をまとめたいと思います。
Thymeleafのフラグメントとは?
フラグメントは、 HTMLの一部を部品として切り出して、複数のページで再利用できる機能 です。
例えば、すべてのページに共通するヘッダーやサイドバーを毎回コピペするのは非効率ですし、修正が必要になったときに全ページを直す必要があります。
フラグメントを使えば:
- ヘッダーやサイドバーを一つのファイルで管理
- 各ページからは
th:replaceで呼び出すだけ - 修正も一か所を変えれば全ページに反映される
公式チュートリアル:
具体例
この画面の上部と左側に表示されているヘッダーとサイドメニューをもとに説明します。
これらはアプリ内の各ページに表示する共通の部分です。
<body>
<header class="header">
<img src="/images/app-icon.png" alt="アイコン" class="app-icon">
<h1 class="site-tittle">SnapShelf</h1>
<div class="user-info" th:if="${currentUsername}">
<span th:text="'担当者:' + ${currentUsername}">担当者名</span>
</div>
<a class="logoutbtn" href="/login">ログアウト</a>
</header>
<body>
<div class="side">
<a class="side-btn" href="/productcreate">
<i class="bi bi-camera-fill"></i>
<span>商品登録</span>
</a>
<a class="side-btn" href="/shelfview">
<i class="bi bi-search"></i>
<span>照会・編集</span>
</a>
<a class="side-btn" href="/comingsoon">
<i class="bi bi-tags"></i>
<span>カテゴリ編集</span>
</a>
<a class="side-btn" href="/comingsoon">
<i class="bi bi-box-seam"></i>
<span>入出庫入力</span>
</a>
</div>
これらのコードを全ページに使用すると、コード量が増えて可読性が下がり、修正も大変です。
フラグメントを使用した結果
これらを共通部分として呼び出しを行っています。コードがシンプルになりました。
<body>
<div th:replace="fragments/header :: header"></div>
<div class="main-layout">
<aside class="sidebar">
<div th:replace="fragments/sidebar :: sidebar"></div>
</aside>
手順
①格納フォルダの作成
htmlファイルを格納しているtemplatesフォルダに、共通部分を保存する fragmentsフォルダを作成します。
src/main/resources/
├ - static/
└ - templates
└ fragments 👈
②フラグメントの作成
作成したfragmentsフォルダに、共通化する部分のhtmlファイルを作成します。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"> <!-- 👈1⃣Thymeleafの名前空間を宣言 -->
<body>
<header class="header" th:fragment="header"> <!--👈2⃣フラグメント名を定義 -->
<!-- 以下は共通化したい内容を書く -->
<img src="/images/app-icon.png" alt="アイコン" class="app-icon">
<a href="/home" style="text-decoration: none;">
<h1 class="site-tittle">SnapShelf</h1>
</a>
<div class="user-info" th:if="${currentUsername}">
<span th:text="'担当者:' + ${currentUsername}">担当者名</span>
</div>
<a class="logoutbtn" href="/login">ログアウト</a>
</header>
</body>
</html>
基本的には再利用したい部分をHTMLで書けば良いのですが、注意点が二つあります。
1.フラグメントファイルの<html>タグにxmlns:thを追加
<html xmlns:th="http://www.thymeleaf.org">
これがないとフラグメントが認識されません。
2.フラグメント名をth:fragmentで定義する
切り出したい部分にth:fragment="名前"をつけます。
<header th:fragment="header">
この名前がほかのページから呼び出すときの識別子になります。
③呼び出し
<body>
<div th:replace="fragments/header :: header"></div>
作成したヘッダーをホーム画面で呼び出しています。
配置したい部分(例ではページの最上部)で、このように書きます。
-
fragments/header→ ファイルパス(.htmlは省略) -
:: header→ フラグメント名
おわりに
例に挙げたヘッダーでは、もともとログインしているユーザーの名前を表示するパラメータを使用していますが、それらも問題なく各ページで使用ができます。
シンプルで便利な機能を知ることができてよかったです。
