Thymeleafとは
所謂、テンプレートエンジンの一つ。
テンプレートとなるファイル(HTMLなど)とデータを組み合わせて、画面を構成する仕組みの一つで、Spring-Bootでの使用が推奨されています。
また、Thmeleafではテンプレートエンジンだけでなく、独自の処理を記述できるようになっています。
例えば、Date型を指定のフォーマットで日付表示したり、数値の桁を合わせたり、など、ユーティリティ機能が提供されています。
対応ファイル
Spring-Bootでは、HTMLファイルでの使用が推奨されています。
HTMLでテンプレートを作成しておくことで、アプリケーションを立ち上げなくとも、プロトタイプとして直接画面表示ができるため、おすすめです。
ほかにも、XMLやJavascript、CSSなどにも対応しています。
Spring-Bootでの使用
Spring-Bootは、MVCに基づいた構成となっているため、Thymeleafの使用がもっとも適しているとか、いないとか。。。
Thymeleafは、MVCのViewに該当します。
Model, Controllerは、Spring-Boot側で実装する仕組みとなっています。
※MVC…Webの処理をModel-View-Controllerの3つに分けてファイルを構成する手法のこと。
JSPと比べて。
たまに、JSPのほうがJavaコードも記述できて便利だ、と耳にします。
しかし、よく考えてください。
確かにそれは便利なのかもしれませんが、膨大な機能を実装していく中で、JavaによるビジネスロジックがJava(ControllerやModel)以外にまで含まれると、追加の対応や不具合の原因がどこで起こっているか、探せますか?
MVCのViewというのは、画面の入力操作,ボタン操作,デザインなどの部分のことを指しており、
決してビジネスロジックを記述する場所ではありません。
簡単はプログラムを書くだけであれば、JSPでJavaコードを記述したくなるのもわかりますが、
目的が違うので、そんな煩雑なシステムを作るのはやめましょう。
基本構文
Thymeleafの簡単な構文について、紹介しておきます。
データの呼び出し
サーバ側で、strという変数へ”TEST”をセットし、Modelへ追加したとしましょう。
Viewにて変数strを参照するには、${}で変数を指定します。
<span te:text="${str}">サンプル</span>
結果
<span>TEST</span>
Thymeleafの属性では上記でよいですが、タグを使用せずに直接出力する場合や、Javascriptなどで変数を参照したい場合などは、”[[“,”]]”(二重のカッコ)で囲んで使います。
<span>[[ ${str} ]]</span>
'[[ ${str} ]]'
文字出力
<span te:text="'Hello World!'">サンプル</span>
Thymeleafの構文で文字列を出力する際は、シングルクォートで囲むのを忘れずに。
上記の場合、出力結果は以下のようになります。
通常<span></span>で囲まれた部分が出力されますが、Thymeleafでは、囲まれている文字列よりもThymeleafによる出力のほうが優先されます。
そのため、上記の”サンプル”部分が消えているわけです。
<span>Hello World!</span>
結合
当然予想できるかもしれませんが、文字列の結合も可能です。
下記のコードも、前述の結果と同じになります。
<span th:text="'Hello ' + 'World!">サンプル</span>
演算
計算もできますよ。
<span th:text="5 + 1"></span>
<span th:text="5 - 2"></span>
<span th:text="5 * 3"></span>
<span th:text="5 / 1"></span>
<span th:text="5 % 2"></span>
条件演算(三項演算)
条件演算子も使用できます。
※条件演算子…「条件 ? Trueの場合 : Falseの場合」の書き方
<span th:text="${str} == 'TEST' ? 'a' : 'b'"></span>
論理演算
OR,ANDによって、条件の記述も可能。
Javaと同様、【OR:||】【AND:&&】の書き方ができます。
比較
条件などの指定ができるので、当然比較演算子もあります。
ただし、HTML上では”<“,”>”などはエスケープされるため、以下の書き方になります。
演算子 | 書き方 |
---|---|
< | < |
> | > |
<= | <= |
>= | >= |
Boolean
比較や論理演算は、当然Booleanの結果で判定しているため、初めからBooleanの値で判定させることも可能です。
よく起こるのは、サーバ側で判定結果をBooleanで格納しておき、Thymleafにて${}を使って条件分岐をしてあげたりします。
URL生成
変数を参照する際は、${}を使用しましたが、URLを生成する場合には、@{}を使用します。
例えば、@{/top/}などをThymeleafで指定することで、”/コンテキストルート/top/”のURLが生成されます。
<form>タグのactionに指定したり、Javascriptにてサブミット先を指定するときによく使います。
<form th:action="@{/top/}">
</form>
<script>
parent.location.href = '[[ @{/top/} ]]';
<script>
ループ
Thymeleafでループ処理をする場合は、th:eachを使用します。
一定回数の繰り返し
一定回数繰り返す場合:th:each=”変数 : ${#numbers.sequence(開始,終了,増分)}”
増分に指定した分、ループごとに2カウントされ、省略時は1となります。
<table>
<!-- 0から3まで繰り返す -->
<tr th:each="i : ${#numbers.sequence(0,3)}">
<td th:text="${i}"></td>
</tr>
</table>
結果:
<table>
<!-- 0から3まで繰り返す -->
<tr>
<td>0</td>
</tr>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
</table>
サーバでセットしたList分繰り返す
List分のループ(Javaでいう拡張for文):th:each=”str : ${list}”
List<String> sample = new ArrayList<String>();
sample.add('aaa');
sample.add('bbbbb');
sample.add('c');
model.addAttribute("lsit", sample);
<ul>
<li th:each="str : ${list}" th:text="${str}"><li>
</ul>
結果:
<ul>
<li>aaa</li>
<li>bbbbb</li>
<li>c</li>
</ul>
ループ中のステータス
ループ中に、ループ回数や最初,最後の判定などのステータスを取得することができます。
取得方法:th:each=”要素を格納する変数, ステータスを格納する変数 : ${変数}”
<div th:each="str, sts : ${list}" th:text="${sts.count} + '番目:' + ${str}" th:styleappend="${sts.last} ? 'background: aqua;': ''"></div>
結果:
<div>1番目:aaa</div>
<div>2番目:bbbbb</div>
<div style="background: aqua;">3番目:c</div>
取得できるステータスは以下と通り
ステータス変数 | 内容 |
---|---|
index | 0始まりの現在のインデックス |
count | 1始まりの現在の要素数 |
size | 繰り返し変数の全要素数 |
current | 現在の要素オブジェクト |
even | 現在の繰り返し位置が偶数の場合true |
odd | 現在の繰り返し位置が奇数の場合true |
first | 現在の繰り返し処理が最初の場合はtrue |
last | 現在の繰り返し処理が最後の場合はtrue |
firstやlastを使用することで、最初(もしくは最後)の行のみの処理や、evenやoddを使用することで、奇数行(もしくは偶数行)にのみ処理することができます。
例えば、偶数行だけ背景色を変更し、行ごとに縞々なテーブルを作る場合なんかは便利ですよね。
条件分岐
th:ifを使用することで、条件に合致する場合にのみ出力することもできます。
<table>
<tr th:each="str, s : ${list}">
<td th:if="${s.count == 1}" th:text="${str}"></td>
</tr>
<table>
<table>
<tr>
<td>aaa</td>
</tr>
</table>
入力値のサブミット
サーバの変数に合わせて出力・サブミットさせる場合は、th:fieldを使用します。
form.setStr("さんぷる");
model.addAttribute("form", form);
※Formクラスには、Stringの変数”str”が定義されているものとします。
<input type="text" th:field="${form.str}"/>
結果:
<input type="text" id="str" name="str" value="さんぷる" />
画面で入力値を変更しサブミットした場合、JavaのFormクラスで定義された変数に、入力した内容がセットされます。
コメント