ベースとなるレイアウトのスタイルを保持する

【前提条件】

[環境]
  • Spring4.0.0
  • Thymeleaf2.1.2
  • Thymeleaf-extras-tiles2 2.1.2

【概要】

前回はベースとなるレイアウトのdivタグを
個別のdivタグに置き換えるサンプルを作りました。

前回のやり方だとdivタグごと置き換わってしまうので、
ベースレイアウトなるページのスタイルを
優先することができませんでした。

今回はベースとなるレイアウトの
スタイルを適用した状態でページを参照させます。

html以外のソースは前回のものを
そのまま使用します。

CSS

今回はCSSファイルを使います。

良くある画面上部にヘッダーがあって、
左側にメニュー、右側にコンテンツと言うページを作ります。

#header-area {
    height: 2em;
}

#body-menu {
    float: left;
    width: 10%;
}

#body-pages {
    float: left;
    width: 90%;
}

【baseLayout.html】

ベースとなるテンプレートから見ていきます。

[前回]
<!DOCTYPE html>
<html>
    <head>
        <title tiles:replace="pageTitle">トップ</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body>
        <div tiles:replace="header" style="background-color: lightblue">
            へっだー
        </div>
        <div>
            <div tiles:replace="menu">
                めにゅ〜
            </div>
            <div tiles:replace="content">
                こんてんつ
            </div>
        </div>
    </body>
</html>
[今回]
<!DOCTYPE html>
<html>
    <head>
        <title tiles:replace="pageTitle">トップ</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <link rel="stylesheet" th:href="@{/css/top.css}" />
    </head>
    <body>
        <div th:id="header-area">
            <span tiles:replace="header" >へっだー</span>
        </div>
        <div th:id="body-contents">
            <div th:id="body-menu">
                <span tiles:replace="menu"></span>
            </div>
            <div th:id="body-pages">
                <span tiles:replace="content">テスト</span>
            </div>
        </div>
    </body>
</html>
[変更点]

前回、divタグに対してtiles:replace属性を適用していました。
今回はdivタグの下にspanタグを作り、
spanタグにtiles:replace属性を適用しています。

【header.html/menu.html/top.html】

topLayout.html以外に関しては
header.htmlを例にして見ていきます。

修正内容は全て同一です。

[前回]
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body>
        <div tiles:fragment="headerContent" style="background-color: lightcoral">
            ヘッダーです。
        </div>
        ここは見せられないよ。
    </body>
</html>
[今回]
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body>
        <th:block tiles:fragment="headerContent">
            ヘッダーです。
        </th:block>
        ここは見せられないよ。
    </body>
</html>
[変更点]

前回はdivタグを使っていましたが、
divタグをth:blockタグに変更します。

th:blockはthymeleafが要素として扱いますが、
実際のHTMLには出力されません。

style属性も不要なので消します。

【実行結果】

続いてHTMLに変換された結果を見ていきます。

[前回]
<!DOCTYPE html>
<html>
    <head>
        <title tiles:replace="pageTitle">トップ</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body>
        <div style="background-color: lightcoral">
            ヘッダーです。
        </div>
        <div>
            <div>
                メニューです。
            </div>
            <div style="background-color: lightsteelblue;">
                コンテンツ
            </div>
        </div>
    </body>
</html>
[今回]
<!DOCTYPE html>

<html>
    <head>
        <title>お知らせページ</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <link rel="stylesheet" href="/sample/css/top.css" />
    </head>
    <body>
        <div id="header-area">
            ヘッダーです。
        </div>
        <div id="body-contents">
            <div id="body-menu">
                メニューです。
            </div>
            <div id="body-pages">
                コンテンツ
            </div>
        </div>
    </body>
</html>

baseLayout.htmlで指定したdivタグのIDが残っているのがわかります。

【まとめ】

前回の方法だと各ページのfragmentに対して
IDやクラスを指定する必要がありました。

th:blockを組み合わせると
今回のようなベースとなるレイアウトの
IDを保持することができます。
ただし、各ページにth:blockを入れる必要があります。

個人的に今回のようなやり方をする
パターンの方が多いのかなと思います。