huruyosi’s blog

プログラミングとかインフラとかのメモです。

spring boot その4 - Thymeleaf の layout を利用して、 ページ固有の title、meta、 style、script タグを出力する

実装したソースは https://github.com/huruyosiathatena/springboot/tree/3cf89896ff8e272b437f988f1c39f2d4a988be0e にあります。

layoutを使って 主コンテンツ以外を出力する

一つ前の記事で Thymeleaf のlayoutを使いました。

huruyosi.hatenablog.com

webページを作成していると、html <div layout:fragment="content"> よりも外側の共通部分にタグを出力する必要が出てきます。 今回は下の4つのタグをページ単位に設定します。

  1. title タグ
  2. meta タグ
  3. style タグ
  4. script タグ

title タグ

方法1) titleタグのテキストをそのまま反映する

テンプレートの head タグ内に titleタグを記載すれば、 レイアウトのtitleタグが置き換わります。

<!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:decorator="layout">
<head>
  <title>a page </title>
</head>
<body>
  <div layout:fragment="content">
        <h1>using template ending Thymeleaf </h1>
        <p class="lead"><span th:text="${message}">param1 content</span></p>
  </div>
</body>
</html>

方法2) layout:title-pattern を使う

github.com

titleタグに layout:title-pattern 属性を設定して タイトルの形式を指定します。

<title layout:title-pattern="$CONTENT_TITLE - $DECORATOR_TITLE">Starter Template for Bootstrap</title> とすると、$CONTENT_TITLE には テンプレートの titleタグのテキストが代入され、 $DECORATOR_TITLEには レイアウトの titleタグのテキストが代入されます。

たとえば thymeleaf.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:decorator="layout">
<head>
  <title>a page</title>
</head>
<body>
  <div layout:fragment="content">
        <h1>using template ending Thymeleaf </h1>
        <p class="lead"><span th:text="${message}">param1 content</span></p>
  </div>
</body>
</html>

と記載すると、出力される html のtitle タグのテキストが a page - Starter Template for Bootstrapになります

metaタグ

コンテンツページに head タグ内に書きます。

<!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:decorator="layout">
<head>
  <title>a page </title>
  <meta name="description" content="ページ固有の情報を thymeleaf の layout に適用する方法 " />
</head>
<body>
  <div layout:fragment="content">
        <h1>using template ending Thymeleaf </h1>
        <p class="lead"><span th:text="${message}">param1 content</span></p>
  </div>
</body>
</html>

と書くと f:id:huruyosi:20150802010759p:plain になります。レイアウトのmetaタグの後ろに挿入されました。

style タグ

metaタグと同様です。

<!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:decorator="layout">
<head>
  <title>a page </title>
  <meta name="description" content="ページ固有の情報を thymeleaf の layout に適用する方法 " />

<style type="text/css">
  h1
  {
    text-align: left;  
  }
</style>
</head>
<body>
  <div layout:fragment="content">
        <h1>using template ending Thymeleaf </h1>
        <p class="lead"><span th:text="${message}">param1 content</span></p>
  </div>
</body>
</html>

と書くと f:id:huruyosi:20150802011217p:plain になります。linkタグと script の間に挿入されました。

scriptタグ

metaやstyleと同様に head タグ内に書くのもアリですが、 body 内の最後に配置します。

レイアウトに <div layout:fragment> を使ってscriptタグを配置する場所を指定します。th:remove="tag"を指定することで、子要素は残し、<div layout:fragment="moreScripts" th:remove="tag">のタグだけを削除します。

tm8r.hateblo.jp

レイアウト

    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="/bootstrap/js/bootstrap.min.js"></script>
    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <script src="/assets/js/ie10-viewport-bug-workaround.js"></script>
    <div layout:fragment="moreScripts" th:remove="tag">
    </div>
  </body>

コンテンツ

<!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:decorator="layout">
<head>
  <title>a page </title>
  <meta name="description" content="ページ固有の情報を thymeleaf の layout に適用する方法 " />

<style type="text/css">
  h1
  {
    text-align: left;  
  }
</style>
</head>
<body>
  <div layout:fragment="content">
        <h1>using template ending Thymeleaf </h1>
        <p class="lead"><span th:text="${message}">param1 content</span></p>
  </div>
  <div layout:fragment="moreScripts">
    <script type="text/javascript">
      alert("exec moreScripts !!");
    </script>
  </div>
</body>
</html>

とすると f:id:huruyosi:20150802012028p:plain になります。依存関係のために順序指定場合、たとえば、jQueryよりも前に実行したい場合には レイアウトが

    <div layout:fragment="beforejQuery" th:remove="tag">
    </div>
    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="/bootstrap/js/bootstrap.min.js"></script>
    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <script src="/assets/js/ie10-viewport-bug-workaround.js"></script>
    <div layout:fragment="moreScripts" th:remove="tag">
    </div>
  </body>

となる。はず。(未検証)