Spring BootとThymeleafでLayoutを共通化する方法 ホームページ制作 | 墨田区

Spring BootとThymeleafでLayoutを共通化する方法

LINEで送る
Pocket

Spring BootとThymeleafでLayoutを共通化する方法のご紹介です。
Spring BootとThymeleafでLayoutを共通化する方法 Thymeleaf の Layoutは、Tiles のように共通レイアウトを定義する仕組みです。

ヘッダ・ナビゲーション・コンテンツ・フッタを、それぞれ部品化することで生産性・保守性の向上が図れます。

以前、「Spring Bootでヘッダ・フッタの共通化する方法」でも書きましたが、今回はもう少し実務に寄った使い方をご紹介します。

最終形はこうです。
Spring BootとThymeleafでLayoutを共通化する方法

一般的な Web サイトの構成ですね。

これを Thymeleaf の Layout dialect でやってみたいと思います。この機能を利用すると、ベースとなるテンプレートページに、各コンテンツページを組み込んでページを生成することができるようになります。




【PR】マジか?!「アレ」してるLINEスタンプっていったい・・・


環境

Spring Boot 1.4.1
Thymeleaf 3.0.2
Windows7
Java8
Eclipse 4.6 Neon

こちらの「Spring Bootで静的ページを配置する方法」を参考に、サンプルアプリを作ってみてください。
Spring Bootで静的ページを配置する方法

Layout作成

まず、templates フォルダー内に layout フォルダーを作り、パーツとなる html ファイルを配備します。
templates-layout内にhtmlを配備
・layout.html
ベースとなるテンプレートページです。
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
  <title layout:title-pattern="$CONTENT_TITLE | $LAYOUT_TITLE">Thymeleaf de layout</title>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link rel="stylesheet" media="all" th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.min.css}" />
  <link rel="stylesheet" media="all" th:href="@{/css/style.css}" />
  <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
  <![endif]-->
</head>
<body>
<div layout:replace="~{layout/header::header}"></div>
<div layout:replace="~{layout/navi::navbar}"></div>
<div id="content" class="clearfix">
<div class="container">
  <div layout:fragment="~{content}" th:remove="tag"></div>
</div>
</div>
<div layout:replace="~{layout/footer::footer}"></div>
<script type="text/javascript" th:src="@{/webjars/jquery/1.12.4/jquery.min.js}"></script>
<script type="text/javascript" th:src="@{/webjars/bootstrap/3.3.7/js/bootstrap.min.js}"></script>
</body>
</html>

Thymeleaf layout dialect 機能を使うにはhtmlタグに
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
と記述します。

タイトルを切り替えるために layout:title-pattern を使います。「$CONTENT_TITLE」がコンテンツページのタイトルで、「$LAYOUT_TITLE」が Web サイトのタイトルになります。
<title layout:title-pattern="$CONTENT_TITLE | $LAYOUT_TITLE">Thymeleaf de layout</title>

次に、部品化したコンテンツページ(ヘッダ部など)を読み込みます。
<div layout:replace="~{layout/header::header}"></div>
これは layout フォルダー内の header.html の header という名前を付けた部分(th:fragment=”名前”)を、この位置に読み込むという意味になります。replace なのでタグごと置換されます。

そして、メインコンテンツの読み込みです。ここが動的に切り替わる部分となります。
<div layout:fragment="content" th:remove="tag"></div>

・header.html
ヘッダ部の html を書きます。ロゴとお問い合わせを配置する仕様です。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<body>
<header id="global-header" layout:fragment="header">
<div class="container">
  <div id="row">
    <div class="col-sm-9 col-md-9">
      <a href="/">ロゴ</a>
    </div>
    <div class="col-sm-3 col-md-3">
      <a href="/contact/" title="Contact us">お問い合わせ</a>
    </div>
  </div>
</div>
</header>
</body>
</html>

・navi.html
ナビバーの html を書きます。各ページへ遷移するグローバルメニューですね。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<body>
<div id="global-navbar" layout:fragment="navbar" class="clearfix">
<nav class="navbar navbar-default" role="navigation">
 <div class="container">
  <div class="navbar-header">
   <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
   <span class="sr-only">Toggle navigation</span>
   <span class="icon-bar"></span>
   <span class="icon-bar"></span>
   <span class="icon-bar"></span>
   </button>
   <span class="navbar-brand visible-xs">メニュー</span>
  </div>
  <div class="navbar-collapse collapse">
   <ul class="nav navbar-nav">
   <li><a href="/" title="ホーム">ホーム<br/><small>HOME</small></a></li>
   <li><a href="/company/" title="会社概要">会社概要<br/><small>COMPANY</small></a></li>
   <li><a href="/service/" title="サービス">サービス<br/><small>SERVICE</small></a></li>
   <li><a href="/recruit/" title="採用情報">採用情報<br/><small>RECRIT</small></a></li>
   </ul>
  </div>
 </div>
</nav>
</div>
</body>
</html>

・footer.html
フッターの html を書きます。コピーライトを書いています。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<body>
<div id="global-footer" layout:fragment="footer">
  <footer>
    <p class="text-right"><small>Copyright(C) Sakakibara Engineering Co.,Ltd, All rights reserved.</small></p>
  </footer>
</div>
</body>
</html>

・index.html
templates 配下の index.html にトップページを配置します。
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/layout}">
<head>
  <title>TOP PAGE</title>
  <meta name="keywords" content="springboot,thymeleaf,layout,トップページ" />
  <meta name="description" content="SpringBootとThymeleafのLayoutを使ってWebサイトを作るサンプルです。ここはトップページです。" />
</head>
<body>
<div layout:fragment="content">
<p style="height:150px;">
トップページです。
</p>
</div>
</body>
</html>

ポイントは
layout:decorate="~{layout/layout}"
です。
layout:decorate を使うことで、layout.html をベーステンプレートして扱うことができます。

ここまでできたら「mvn clean」、「mvn test」を実行して動作を確認します。
こんなページができると思います。
SpringBoot Thymeleaf Layoutサンプル起動

おお、いい感じですねー^^

ページを増やしてみる

では、早速ページを増やしてみましょう。
templates 配下に contents フォルダーを作って、下図のようにページを配備します。
templates - contents内にhtml追加

・company.html
会社情報のページを作ります。内容は index.html をコピペして文言を変えた程度ですので全ページ分の掲載は割愛します。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/layout}">
<head>
  <title>会社情報</title>
  <meta name="keywords" content="springboot,thymeleaf,layout,会社情報" />
  <meta name="description" content="SpringBootとThymeleafのLayoutを使ってWebサイトを作るサンプルです。ここは会社情報のページです。" />
</head>
<body>
<div layout:fragment="content">
<p style="height:150px;">
会社情報のページです。
</p>
</div>
</body>
</html>

他のページもコピペで作ってみてください。

・IndexController
各ページへ遷移できるように、コントローラークラスを変更します。
package jp.demos.spbfe;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class IndexController {
  @RequestMapping(value = "/", method = RequestMethod.GET)
  String index() {
    return "index";
  }
  @RequestMapping(value = "/company/", method = RequestMethod.GET)
  String comapny() {
    return "contents/company";
  }
  @RequestMapping(value = "/service/", method = RequestMethod.GET)
  String service() {
    return "contents/service";
  }
  @RequestMapping(value = "/recruit/", method = RequestMethod.GET)
  String recruit() {
    return "contents/recruit";
  }
  @RequestMapping(value = "/contact/", method = RequestMethod.GET)
  String contact() {
    return "contents/contact";
  }
}

「mvn clean」、「mvn test」を実行して動作を確認します。
各グローバルメニューをクリックしてページ遷移を確認しましょう。
SpringBoot Thymeleaf Layoutサンプル ページ遷移

おおお、うまくいきましたねー^^

参考サイト

Rename layoutdecorator to layoutdecorate · Issue #95 · ultraq-thymeleaf-layout-dialect · GitHub
[MAJOR FEAT] Fragment Expressions · Issue #451 · thymeleaf-thymeleaf · GitHub

まとめ

Thymeleaf の Layout を使うと、ページを部品化・共通化できて、とてもいい感じに仕上がります。同じ記述を何度も書くなんて生産性も保守性も悪いですからね。これをうまく活用して、開発効率を上げたいものです。

あ、Tiles に慣れた方ならすぐに使えるようになると思いますよー^^

皆さんも試してみてください。

おすすめ書籍 – 私はこの書籍1冊で Spring Boot を習得できました^^

SpringBootプログラミング入門

新品価格
¥3,024から



おつかれさまでした。

LINEで送る
Pocket

この記事がお役に立ちましたら シェア をお願いいたします。

コメントを残す

コメント(必須)

お名前 (必須)
メールアドレス
(アドレスは公開されません)

Trackback URL