ページ

2015/04/14

Thymeleafのlayoutを使う

|

Spring BootとThymeleafの組み合わせにおいて、th:fragmentなどの使い方は分かったが、共通のレイアウト(<head>なども含めて)を集約するにはどうすればいいのかわからなかった。
例によってSaganを見てみると、layout:というのを使っていた。
Thymeleafの日本語ドキュメントのこのページを見ていたら見つからなかったが、こちらには書いてあった。

これによると、Thymeleaf Layout Dialectを使えばいいらしい。

Dependency

Dependencyとして

nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:1.2.1

が必要とのことだったが、Spring Bootだからもしかして・・・

./gradlew dependencies | grep thymeleaf

としてみると、やはり

+--- org.springframework.boot:spring-boot-starter-thymeleaf:1.2.3.RELEASE
|    +--- org.thymeleaf:thymeleaf-spring4:2.1.4.RELEASE
|    |    +--- org.thymeleaf:thymeleaf:2.1.4.RELEASE
|    \--- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:1.2.7

というように、すでに含まれていた。なので、Spring Bootでspring-boot-starter-thymeleafを使っているなら特に何もしなくて良い。

LayoutDialect

次に、以下のようなコードを追加する必要があるとのことだったが

@Bean
public SpringTemplateEngine templateEngine() {
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    ...
    templateEngine.addDialect(new LayoutDialect());
    return templateEngine;
}

これは追加しなくて良いようだった。

layout.html

共通レイアウトとして、今回はtemplates/layout.htmlを作成した。
XMLネームスペースとしてlayoutを定義し、
コンテンツを埋め込みたい部分のタグにlayout:fragment="fragment名"を定義する。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
:
    <title layout:title-pattern="$DECORATOR_TITLE - $CONTENT_TITLE">TODO</title>
:
<div layout:fragment="content">
    <p>Static content for prototyping purposes only</p>
</div>
:
</html>

$DECORATOR_TITLEは、layout.html側の<title>の値。
つまり上記ではTODOとなる。
$CONTENT_TITLEは、埋め込むページ側の<title>の値。

各ページ

埋め込む側のページでは、例えば以下のようにしてレイアウトを適用する。
layout:decoratorの部分で、どのレイアウトを使うかを指定している。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorator="layout">
<head>
    <title>Main</title>
</head>
<body>

<div layout:fragment="content">
(このページのコンテンツをここに定義)
</div>

</body>
</html>

結果

以上の記述で実行すると、以下のようにレイアウトが適用される。

<!DOCTYPE html>
<html>
:
    <title>TODO - Main</title>
:
<div>
(このページのコンテンツをここに定義)
</div>
:
</html>

0 件のコメント: