Spring Boot CLI + Thymeleafに関する自分用メモです
Thymeleafとは
Javaのテンプレートエンジンライブラリ
アプリケーションのデータやテキストを表示するための雛型
<テンプレートの必要性>
サーバプログラムでHTML文書を全て作成させることもできますが、デザインとロジックを分離したいじゃん、というのがテンプレートの必要性。
<JSPの問題点>
JSPのスクリプトレット(<% out.println(new java.util.Date()); %>など)でJavaコードのロジック埋め込んだら、結局デザインとロジック分離できてないじゃん、というのがJSPの問題点。
<Thymeleafの利点>
比較的コードが混在しない。また、Thymeleafのタグを埋め込んだ文書でも、形式が崩れることなく、静的に開くことができる。つまり、サーバアプリでパースすることなく、HTMLブラウザ(IE,chrome,etc..)やWordPressビジュアルエディタで開いてもちゃんと表示される。この特性をナチュラルテンプレーティングという。
<テンプレートモード>
デフォルトで処理できる6種類のテンプレートのこと。
- XML
- Valid XML
- XHTML
- Valid XHTML
- HTML5
- Legacy HTML5
独自定義もできるらしい。Validは仕様に沿っていること。
スタンダードダイアレクト
DOMを操作するタグ、と理解しておけば当座は問題なさそう。
詳細は公式ドキュメント参照
使用例
-
<input type="text" name="name" th:value="${str}" />
Thymeleafでこのinput要素を処理することで、value=(strの値)が設定される。文字が入力されたテクストボックスができる。
静的にファイルを開いた際はth:...は無視される。初期値がないテクストボックスが生成される。 -
<p ht:text="${greeting}">Overridable String</p>
Thymeleafで処理すると、「Overridable String」が「${greeting}」を変換した内容に置き換わります。
<変数へのアクセス>
- ModelオブジェクトやModelAndView
<model>.addAttribute(attribute_name, value);
で、Modelオブジェクトに変数を持たせることができます。 - パラメータで渡す
<domain>/profile?age=24
のようにパラメータを渡した際、${param.age[0]}でアクセスできます。
つまり、paramにクエリパラメータ群、.key[index]で値にアクセスできます。
<変数式とOGNL>
${{ }}のように書いたブロックのことを変数式という。
変数式の中には、OGNLを書く。
OGNLは、Object-Graph Navigation Laungageの略で、Javaオブジェクトの値を参照するための式言語です。
<式のユーティリティオブジェクト>
メソッドを簡便に使用できるようにするためのオブジェクト
- #dates: java.util.Date オブジェクト用のユーティリティメソッド: フォーマット、コンポーネントの抽出など。
- #calendars: #dates に似ていますが java.util.Calendar オブジェクト用です。
- #numbers: 数値オブジェクト用のユーティリティメソッド。
- #strings: String オブジェクト用のユーティリティメソッド: contains, startsWith, prepending/appending, など。
- #objects: オブジェクト一般のユーティリティメソッド。
- #bools: 真偽値評価用のユーティリティメソッド。
- #arrays: 配列用のユーティリティメソッド。
- #lists: リスト用のユーティリティメソッド。
- #sets: セット用のユーティリティメソッド。
- #maps: マップ用のユーティリティメソッド。
- #aggregates: 配列やコレクション上での集約処理用ユーティリティメソッド。
- #messages: #{…} と同様に、変数式内での外部化メッセージを取り扱うためのユーティリティメソッド。
- #ids: (例えば、イテレーション結果などの)繰り返し処理内でid属性を取り扱うためのユーティリティメソッド。
( 引用元:公式ドキュメント )
ここの使い方は後ほど追記します。
<テキストリテラルの記述>
th:text = "You are an user of Qiita"
th:text = "'You are ' + 'an user of Qiita'" <!-- 文字列結合(+) -->
th:text = "'You are ' + ${param.name} + '.'" <!-- 文字列結合(+) -->
th:text = "|You are ${param.name}.|" <!-- リテラル置換(|)で変数をそのまま書ける -->
<メッセージ式>
#{...}
プロパティファイルに書いた値にアクセスできる。公式ドキュメントでは、「テキストの外部化」といっている。
ヘッダー・フッターに表示させる商標とか社名に使えそう。
- main/resourceフォルダ配下にmessage.propertiesというファイルを作る
- 「オブジェクト名.属性名=値」の形式で記述(改行区切り)
※ローカライズは後で追記
<リンクURL式>
@{ ドメイン以下のURL }
中に変数を入れることができる。会員ページや商品ページに使うでしょう。
<選択変数式>
*{ オブジェクト }
選択変数式を持つブロックで、オブジェクトの指定を省略することができる。
<div th:object="${session.student}">
<p>国語の点数:<span th:text="*{kokugo}"></span>-</p>
<p>算数の点数:<span th:text="*{math}"></span>-</p>
</div>
エスケープしないでテキストを表示する
Thymeleafはデフォルトで、テキストを出力する際、HTMLタグをエスケープ(HTMLタグとしての効果を無効化)する。つまり、th:textで定数や変数を出力した際は、<a href="..">text</a>などが変換されない。
th:utext
と書けば、エスケープしないで出力する。
Model と ModelAndView の違い
- Model
ビジネスロジックを持つ
テンプレートを利用するためのデータを持たないため、Modelオブジェクトをreturnで返してもテンプレートは表示できない。
URLにマッピングされているメソッドで文字列を返せば、そのファイル名を持つテンプレートを開く。拡張子は不要( return "sitemap"; ) - ModelAndView
ビジネスロジックを持っているのに加え、テンプレートを利用するためのデータを持つ
テンプレート情報を持つModelAndViewをreturnで返すことで、テンプレートを表示できる。
ModelAndViewオブジェクトのsetViewnameでテンプレートのファイル名を渡せば、オブジェクトがテンプレートの情報を保持できる。テンプレート情報を持つModelAndViewオブジェクトを返せば、テンプレートを開くことができる。
HTTPレスポンスが404だった際の確認事項
- RequestMappingの設定
-
@RequestMappingの属性が複数あるのに、value="/"というように属性名を指定するのを忘れていないか
※属性が1つの時は@RequestMapping("/")と省略可能 - 遷移元のformのaction属性の値とRequestMappingがあっているか
-
@RequestMappingの属性が複数あるのに、value="/"というように属性名を指定するのを忘れていないか
- htmlファイルをtemplatesに格納しているか
※ フォルダ名が違っていて、ビルドはできてもアクセス時にエラーになる事象があった。
コメント
- <!-- ... --> 標準的なHTML/XMLコメント
静的にファイルを開いた際も、Thymeleafとしてパースしても、どちらでも表示される。 - <!--/* ... */--> パーサーレベルのコメントブロック
Thymeleafとしてパースすると、削除される。
静的にファイルを開いた際は、表示される。
※複数行にまたぐ時に下記のように書いても良い。
<!--/*-->
...
<!--*/-->
※これは の間にあるもの全てを完全に削除するため。 - <!--/*/ ... /*/--> Thymeleafプロトタイプのみのコメントブロック
Thymeleafとしてパースすると、表示される。削除される。
静的にファイルを開いた際は、削除される。
※パーサーレベルのコメントブロックの逆
コメントと表示のされ方の対応表
書き方 | 種類 | パース後の表示有無 | 静的に開いた際の表示有無 |
---|---|---|---|
<!-- ... --> | 標準的なHTML/XMLコメント | タグとテキストあり | タグとテキストあり |
<!--/* ... */--> | パーサーレベルのコメントブロック | なし | タグとテキストあり |
<!--/*/ ... /*/--> | Thymeleafプロトタイプのみのコメントブロック | テキストのみあり | なし |
参照:Thymeleaf公式ドキュメント#コメントとブロック | |||
※擬似的な th:block タグについては、まだ試す環境を作れていないので後日検証して追加する |