【Thymeleaf】フラグメント(共通パーツ)でヘッダー・フッターを分けよう
新人
「先輩、Thymeleafで作ったページが増えてきたんですけど、毎回ヘッダーやフッターを同じように書くのが面倒なんです…」
先輩
「それなら、Thymeleafのフラグメントを使うといいよ。共通パーツとして、ヘッダーやフッターを分けて管理できるんだ。」
新人
「フラグメントって何ですか? どうやって使うんですか?」
先輩
「じゃあ、まずはThymeleafのフラグメントについて基本から解説していこうか。」
1. フラグメントとは何か?
Thymeleafのフラグメントとは、HTMLファイルの一部分を切り出して、他のテンプレートから呼び出せるようにした共通パーツのことです。テンプレートエンジンであるThymeleafを使うと、同じコードを何度も繰り返し書く必要がなくなり、開発効率が大きく向上します。
たとえば、ヘッダーやフッターなど、どのページでも共通で使うパーツはフラグメントとして定義しておき、それを必要な場所で呼び出せばよいのです。
以下は、header.htmlというファイルにフラグメントを定義した例です。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>共通ヘッダー</title>
</head>
<body>
<div th:fragment="header">
<header>
<h1>共通のヘッダー部分です</h1>
<nav>
<a href="/">ホーム</a> |
<a href="/about">このサイトについて</a>
</nav>
</header>
</div>
</body>
</html>
このようにth:fragment属性を使って定義した部分は、他のテンプレートからth:replaceで読み込むことができます。次の章で、どうしてヘッダーやフッターを分けるべきなのかを見ていきましょう。
2. なぜヘッダーやフッターを共通化するのか
Webアプリケーションを開発していると、すべての画面に共通して表示する部分がたくさん出てきます。例えば、
- サイトのロゴやタイトルを含むヘッダー
- ナビゲーションバー
- 著作権表示などを含むフッター
これらを毎回ページごとにHTMLとして記述していると、次のような問題が発生します。
- 複数ファイルの修正が必要になり、手間がかかる
- 記述ミスが起こりやすく、バグの原因になる
- 統一感のあるデザインを保ちにくい
そこで役立つのが、Thymeleafのフラグメントによる共通化です。フラグメントを使えば、ヘッダーやフッターを一箇所で管理でき、保守性と再利用性が格段に向上します。
実際に、他のテンプレートファイルからヘッダーを読み込むには、以下のようにth:replaceを使います。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>トップページ</title>
</head>
<body>
<div th:replace="fragments/header :: header"></div>
<main>
<p>ここがメインのコンテンツ部分です。</p>
</main>
<div th:replace="fragments/footer :: footer"></div>
</body>
</html>
このように、fragments/headerのファイルからheaderフラグメントを、fragments/footerのファイルからfooterフラグメントを読み込むことができます。
次回は、具体的にヘッダーやフッターをどのようにファイル分割し、レイアウトテンプレートに組み込むのかを詳しく見ていきます。
3. フラグメントを使ったヘッダーの作り方
ここからは、Thymeleafのフラグメントを使って実際にヘッダーを作る方法を詳しく見ていきましょう。まずは、ヘッダー部分だけを定義したHTMLファイルを作成します。このファイルはたとえば、src/main/resources/templates/fragments/header.htmlに保存します。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
</head>
<body>
<div th:fragment="header">
<header>
<h1>マイサイト</h1>
<nav>
<ul>
<li><a href="/" th:href="@{/}">ホーム</a></li>
<li><a href="/profile" th:href="@{/profile}">プロフィール</a></li>
<li><a href="/contact" th:href="@{/contact}">お問い合わせ</a></li>
</ul>
</nav>
</header>
</div>
</body>
</html>
このようにth:fragment="header"を指定することで、この部分を他のテンプレートから読み込めるようになります。HTMLファイルの構造は通常通りですが、フラグメントとして使う部分はdivやsectionタグなどで囲み、th:fragmentで明示しておくことが大切です。
4. フラグメントを使ったフッターの作り方
次に、フッターを共通パーツとして定義してみましょう。こちらも同様にフラグメントを使って作成し、たとえばfragments/footer.htmlという名前で保存します。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
</head>
<body>
<div th:fragment="footer">
<footer>
<p>© 2025 マイサイト All Rights Reserved.</p>
<p><a href="/privacy" th:href="@{/privacy}">プライバシーポリシー</a></p>
</footer>
</div>
</body>
</html>
このようにしておけば、全ページでこのfooterフラグメントを共通して利用できます。Webサイトの更新や変更があったときでも、この1ファイルを修正するだけで済むため、非常に保守性が高くなります。
また、ナビゲーションの追加や著作権表記の変更などがあった場合でも、フッターのHTMLファイルを1箇所編集するだけで、すべてのページに反映されるため、非常に便利です。
5. レイアウトテンプレートからフラグメントを読み込む方法
実際に作成したヘッダーやフッターのフラグメントを、他のページのテンプレートから読み込んで利用するには、th:replaceを使います。
たとえば、home.htmlのようなページテンプレートで共通ヘッダーとフッターを読み込みたい場合、以下のように記述します。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>ホームページ</title>
</head>
<body>
<div th:replace="fragments/header :: header"></div>
<main>
<h2>ようこそ!</h2>
<p>このページはThymeleafのテンプレートを使って作成されています。</p>
</main>
<div th:replace="fragments/footer :: footer"></div>
</body>
</html>
th:replace="fragments/header :: header"という指定で、fragments/header.htmlファイル内のheaderフラグメントを読み込み、HTMLとして埋め込んでくれます。同様にfooterも読み込まれ、1ページの中にヘッダー・メイン・フッターがバランスよく構成される形になります。
このとき注意してほしいのは、フラグメントの定義と呼び出しが一致していることです。ファイルパスやフラグメント名が間違っていると、テンプレートエンジンであるThymeleafは読み込みに失敗し、画面に何も表示されなくなってしまうことがあります。
また、Pleiades+Gradleで構成されたプロジェクトでは、テンプレートファイルはsrc/main/resources/templates配下に配置されるようにしてください。ファイルパスが間違っていると、@Controllerで返したビュー名に対応するHTMLが正しく見つからなくなります。
Thymeleafはテンプレートエンジンとして、柔軟かつ簡潔にHTMLの共通パーツを管理できる機能を提供しています。フラグメントの活用により、初心者でも効率よく、そして保守しやすいWeb画面の設計が可能になります。
次回は、フラグメントの読み込みで起こりやすいミスや、実務で役立つヒントを紹介していきます。
6. よくあるミスとその対処法
Thymeleafのフラグメントを使う際、初心者がつまずきやすいポイントがいくつかあります。ここでは、よくあるミスとその対処方法について解説します。
① ファイルパスの間違い
フラグメントのファイルを読み込むときのパスは、src/main/resources/templatesからの相対パスで指定します。たとえば、templates/fragments/header.htmlにあるフラグメントを読み込むには、次のように記述します。
<div th:replace="fragments/header :: header"></div>
fragments/headerのように拡張子は書かず、.htmlを省略します。もしtemplates/header.htmlにある場合は、次のようになります。
<div th:replace="header :: header"></div>
② フラグメント名の書き間違い
th:fragmentで定義した名前と、th:replaceで呼び出す名前が一致していないと、テンプレートが表示されません。以下のように定義していた場合、
<div th:fragment="siteHeader">
<header>ヘッダーの中身</header>
</div>
呼び出し側はこう書かないと読み込まれません。
<div th:replace="fragments/header :: siteHeader"></div>
③ 呼び出し位置のHTML構造が不正
呼び出し先のフラグメント内に<html>や<body>タグを含めていると、読み込み先との構造が二重になってレイアウトが崩れることがあります。フラグメント専用のHTMLファイルは、構造を簡素にして、必要な部分だけを定義するようにしましょう。
7. 実務で使える開発のポイント
Thymeleafのフラグメントは、実務でのチーム開発においても非常に役立つ機能です。特に画面レイアウトの共通化や、複数人で作業する場合の役割分担において、フラグメントを活用することで効率が大きく上がります。
① ディレクトリ構成を明確にする
フラグメントは専用ディレクトリ(例:fragments/)にまとめておくと、他のテンプレートと区別がつきやすく、メンテナンスしやすくなります。
templates/fragments/header.htmltemplates/fragments/footer.htmltemplates/layouts/base.html
② デザイナーとプログラマーの分業がしやすくなる
HTMLの共通パーツをフラグメントとして分離しておくことで、フロントエンド担当者とバックエンド担当者がそれぞれ自分のファイルに集中して作業できます。これはチームで開発する場合にとても大切な考え方です。
③ 誰が見てもわかる命名規則を決める
たとえば、「header」「footer」「sidebar」など、明確な名前を付けることで、読み手の理解度が上がり、保守性も高まります。また、複数のプロジェクトで共通の命名ルールを使うことで、作業者が変わってもスムーズに対応できます。
④ @Controllerとテンプレート名を整理する
Springの@Controllerでは、return "home";のようにテンプレート名を返しますが、そのテンプレートの中で読み込むフラグメントも、統一されたルールで配置・命名されていると非常に扱いやすくなります。
8. 今後のWeb開発でフラグメントを活用するための考え方
今後のWebアプリ開発において、再利用性と保守性はますます重要になってきます。Thymeleafのフラグメントを積極的に活用することで、以下のようなメリットがあります。
- デザインの変更に迅速に対応できる
- 同じパーツの重複を避けられる
- コードの見通しがよくなり、学習コストも低い
特に初心者のうちは、画面を作るたびにHTMLを毎回コピーしてしまいがちですが、フラグメントを使うことによって「1つの場所で管理する」意識を持つことができます。これは将来的にチーム開発や大規模アプリケーションに携わるときに大きな強みとなります。
また、テンプレートエンジンであるThymeleafは、HTMLに近い記法で記述できるため、HTMLの基本を理解している初心者にも非常に扱いやすいです。Pleiadesを使ったSpring Boot開発でもスムーズに統合でき、Gradleプロジェクトとの相性も良好です。
最後に、フラグメントを使うときは、「変更が発生する可能性が高い部分」や「複数ページで使い回す部分」を中心に共通化を進めていきましょう。すべてをフラグメント化すればよいわけではなく、使いどころの見極めが重要です。
これからThymeleafを使ってWebアプリを開発していく中で、フラグメントの使い方をしっかりと身につけておくことで、開発効率や品質の向上につながります。初心者の段階からこの設計思想を理解しておくと、将来の成長が大きく広がるはずです。