Thymeleaf Layout Dialectのご紹介

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

フロントエンドの実装するさいに、共通で扱うCSSやJavascriptは一括で管理したいものです。

今回の案件はThymeleafをテンプレートエンジンとして使っているのですが、
そういったケースにおいてはThymeleaf Layout Dialectを用いることで割と簡単にできました。

導入方法

Spring InitializrでWebとThymeleafを含んだプロジェクトを作成すれば、
Thymeleaf Layout Dialectが含まれた形のプロジェクトが作成されます。

Spring Tool Suiteで作成する際も、Spring Starter Projectから同様の手順です。

実装方法

Controller

/ と /index2 にアクセスした際に、ページが表示できるようにします。

src/main/java/demo/indexController.java

package demo;

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="/index2",method=RequestMethod.GET)
	String index2(){
		return "index2";
	}
}

上記の実装で、
/ にアクセスした際は index というテンプレートが、
/index2 にアクセスした際は index2 というテンプレートが呼ばれる事になります。

Template decorator編

Thymeleaf Layout Dialectdでは、共通の箇所のことをDecoratorと呼ぶようです。

Decoratorの実装は以下のようになります。

/src/main/resources/templates/layout.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"
>
<head>
<meta charset="UTF-8" />
<title>Insert title here</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>

<th:block layout:fragment="layout-content">
    <p>Default layout content</p>
</th:block>

</body>
</html>

今回のサンプルではDecoratorを適用した場合、CDNからjqueryを共通で読むといった実装にします。

13~15行目の箇所に、各々のページで設定した内容が入ることとなります。

Template fragment編

実装する各々のページはfragmentと呼ぶようです。

今回はdecoratorが適用できていることを確認したいだけなので内容はページ名の表示以外は同一としてあります。

/src/main/resources/templates/index.html

<div layout:decorator="layout">
    <th:block layout:fragment="layout-content">
        <p>ページ1</p>
    </th:block>
</div>

/src/main/resources/templates/index2.html

<div layout:decorator="layout">
    <th:block layout:fragment="layout-content">
        <p>ページ2</p>
    </th:block>
</div>

1行目はdecoratorのファイル名を拡張子無しで指定しています。

2行目はdecorator内で指定したfragmentの名前を指定しています。

このようにすることで、各々のページにdecoratorが適用されて表示されることになります。

結果

以下のURLにアクセスし正しく適用されていることを確認します。

http://localhost:8080/

index1

http://localhost:8080/index2

index2

decoratorで指定した部分、fragmentで指定した部分ともに反映されていることがわかるかと思います。

まとめ

テンプレートエンジンを採用する際に、共通で使うJavascriptやCSSのライブラリをどのように一元管理するかといったことは、
必ずといっていいほど課題になります。

こういった実装でライブラリの管理を容易にし、本来の開発に本腰を入れたいものです。