Help us understand the problem. What is going on with this article?

Thymeleafでヘッダーフッターを共通化する方法

概要

Spring BootとThymeleafを使って作るWebアプリで、各htmlのページに共通しているヘッダーやフッターを共通化する方法

環境

  • Java8
  • Spring Boot
    • version: 2.1.9.RELEASE
  • Thymeleaf
    • version: 3.0.11.RELEASE
  • Eclipse
    • version: 2018-09 (4.9.0)

サンプル

ディレクトリ構成

Java側は省略しますが、templateと静的コンテンツの配置はこんな感じ。

dir
src/main/resources
├── static
│   ├── css
│   │   ├── common.css
│   │   └── top.css
│   └── js
│       └── datepicker.js
└── templates
    ├── common.html
    └── index.html

SpringBootはtemplates配下のHTMLからCSSやJSファイルを参照する場合、
staticがルートディレクトリになるので、このような構成にしてます。

共通部品用のcommon.htmlを作成する

common.html
<html xmlns:th="http://www.thymeleaf.org">
<!-- (1)共通にしたいheadをfragment化する -->
<head th:fragment="meta_header(title,links,scripts)">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <!-- (2)共通で読み込むCSS/JS -->
    <link rel="stylesheet" href="/css/common.css" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <!-- (3)タイトルのフォーマット -->
    <title th:text="${title}+' | sample app'">各ページタイトル | sample app</title>

    <!-- (4)各View固有で読み込むもの -->
    <th:block th:replace="${links} ?: _" />
    <th:block th:replace="${scripts} ?: _" />
</head>
<body>
    <!-- (5)body内で共通化したい部品をfragment化する -->
    <header th:fragment="header">
        <h1><a th:href="@{'/'}">sample app</a></h1>
    </header>
</body>
</html>

解説

(1) fragment名は引数を取れるのでtitle,links,scriptsを引数に設定する
(2) 各ページで共通に読み込むCSS/JSを記載する
(3) 引数のtitleを使ってth:text=""にページタイトルのフォーマットを設定する
(4) 各ページで読み込むCSS/JSをth:replaceを使って差し込む
処理なしトークン(?: _)を使うことで、${links}がnullだった場合はth:block自体が無かったものになる
(5) body内でも共通化したいものがあったらth:fragmentを使って部品化する

各html側で呼び出す

index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<!-- (1)共通headerで置き換える -->
<head th:replace="common :: meta_header('top',~{::link},~{::script})">
    <!-- (2)このページ固有で読み込むCSS/JS -->
    <link rel="stylesheet" th:href="@{/css/top.css}" />
    <script type="text/javascript" th:src="@{/js/datepicker.js}"></script>
</head>
<body>
    <!-- (3)共通部品を呼び出す -->
    <div th:replace="common :: header"></div>
    <h2>top page</h2>
</body>

解説

(1) headercommon.htmlで定義したものに引数を渡して置き換える
(2) このページ(このサンプルではindex.html)固有で読み込むファイルを定義する
(3) 共通部品もth:replace="ページ名::fragment名"で置き換える

参考

Spring Bootでヘッダ・フッタの共通化する方法
Tutorial: Using Thymeleaf

tamorieeeen
Web系フルスタックフリーランスエンジニア。Java/PHP/MySQL/HTML/CSS/JavaScript/AWS/RubyとGoは勉強中
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした