PS: 私たちの熱意が三分間の熱だけであれば、信仰の試練を完了することはできません。混乱が訪れたとき、最初にすることはしばしば逃げることです。どんなスキルも短期間で習得することはできませんが、十分に続ければ、時間があなたに答えを与えてくれるでしょう。
上篇文章では、Thymeleaf テンプレートの依存関係、基本属性、および使用方法について簡単に紹介しました。以下では、Thymeleaf における一般的な構文について以下のいくつかの側面から紹介します:
- 表現
- 文字列の結合
- 条件比較
- switch 多分岐
- ループ
- その他の演算子
- インライン
- テスト効果
以下に示す部分パラメータまたは変数の具体的な値は次のとおりです:
// テスト用の値を渡す
model.addAttribute("name", "jzman");
model.addAttribute("gzh", "<b>躬行之</b>");
model.addAttribute("user", new User("manu"));
model.addAttribute("id", "123456");
model.addAttribute("flag", false);
model.addAttribute("value", 10);
// ループ文のテスト用
model.addAttribute("list", mUserList);
// spanタグのid, cssインラインテスト用
model.addAttribute("idName", "css");
// cssスタイルで使用する色の値, cssインラインテスト用
model.addAttribute("color", "#FF0000");
表現#
Thymeleaf で一般的な表現には以下のようなものがあります:
- メッセージ表現:
#{}
を使用して対応するプロパティファイルから値を取得します; - 変数表現:
${}
を使用して変数の値を取得します。これらの変数の値は一般的にバックエンドから渡されます; - 選択変数表現:
th:object
属性と組み合わせて、*{}
を使用してth:object
で指定されたオブジェクトの属性値を取得します; - リンク URL 表現:
@{}
を使用してリンクアドレスを示し、簡単にそのリンクアドレスにパラメータを渡すことができます。
上記の表現の使用方法は以下の通りです:
<ul th:object="${user}">
<!--メッセージ表現-->
<li>メッセージ表現:<span th:text="#{home.title}">Hello World!</span></li>
<!--変数表現-->
<li>変数表現:<span th:text="${name}">Hello World!</span></li>
<!--選択変数表現-->
<li>選択変数表現:<span th:text="*{username}">Hello World!</span></li>
<li>選択変数表現:<span th:text="${user.username}">Hello World!</span></li>
<!--リンク表現-->
<li>リンク表現:<a href="default.html" th:href="@{default.html}">Default Page.</a></li>
<li>リンク表現:<a href="default.html" th:href="@{http://localhost:8080/{path}/i18n}">I18n Page.</a></li>
<li>リンク表現:<a href="default.html" th:href="@{http://localhost:8080/message(id=${id})}">Message.</a></li>
</ul>
上記のコードの th 属性はすべて Thymeleaf に対応する Html 属性定義の属性であり、メッセージ表現の例では、resources フォルダ内の home.properties ファイルに定義された home.title の値を取得しています。
変数表現の例では、バックエンドから渡されたname
という名前の変数の値を取得しています。
選択変数表現の例では、th:object
属性で指定されたオブジェクトuser
のusername
の値を取得しています。th:object
属性を設定しない場合、${}
と*{}
には違いがなく、どちらもオブジェクトの属性値にアクセスできます。
リンク表現の例では、<a>
タグにリンクアドレスを指定し、必要なパラメータを簡単に指定できます。
バックエンドがどのように変数name
とオブジェクトuser
をページに渡しているかを見てみましょう。コードは以下の通りです:
文字列の結合#
文字列の結合は一般的に+
を使用して文字列同士を結合します。また、二重パイプで文字列内容を囲むことで結合を実現することもできます。使用方法は以下の通りです:
<!--文字列の結合-->
<!--1. +を使用-->
<li><span>+を使用: </span><span th:text="'My name is '+${name}+'!'">Default</span></li>
<!--2. |を使用-->
<li><span>|を使用: </span><span th:text="|My name is ${name}!|"></span></li>
テスト結果は以下の通りです:
1.+を使用: My name is jzman!
2.|を使用: My name is jzman!
条件比較#
Thymeleaf の条件判断文はth:if
とth:unless
です。th:if
は条件が満たされたときに実行され、th:unless
は条件が満たされないときに実行されます。さらに、Thymeleaf で一般的な比較演算子は以下の通りです:
- gt (>):大きい
- lt (<):小さい
- ge (>=):大きいまたは等しい
- le (<=):小さいまたは等しい
- not (!):否定
- eq (==):等しい
- neq/ne (!=):等しくない
上記の比較演算子に対応する文字列は各比較演算子のエイリアスです。例えば、大なり記号はgt
で表すことができます。このようにする理由は、Thymeleaf テンプレートが XML 文書内で使用できるため、XML 文書内の属性値では<
や>
タグを使用できないからです。もちろん、ここではプロジェクト開発のためにどちらの方法を選択しても自由です。使用方法は以下の通りです:
<!--条件比較--value=10-->
<li th:if="${value} gt 9"><span>gt(>) </span><span th:text="|${value}|+'>9'">Default</span></li>
<li th:if="${user} ne null"><span>ne(!=) </span><span th:text="'User object is not null!'">Default</span></li>
<!--if/unless-->
<li th:if="${value} gt 9"><span>if </span><span th:text="|${value}|+'>9成立時のみ実行'">Default</span></li>
<li th:unless="${value} gt 11"><span>unless </span><span th:text="|${value}|+'>11不成立時のみ実行'">Default</span></li>
テスト結果は以下の通りです:
gt(>) 10>9
ne(!=) User object is not null!
if 10>9成立時のみ実行
unless 10>11不成立時のみ実行
switch 多分岐#
switch...case
文も条件文に属し、th:case="*"
はデフォルトの選択項目を示します。使用方法は以下の通りです:
<li th:switch="${name}">
<p th:case="jzman">彼の名前はjzmanです。</p>
<p th:case="manu">彼の名前はmanuです。</p>
<!--default-->
<p th:case="*">その他</p>
</li>
テスト結果は以下の通りです:
これはjzmanです
ループ#
テンプレートコードでfor
ループを使用する方法は以下の通りです:
<li><span>インデックスなし</span>
<table>
<tr th:each="user:${list}">
<td th:text="${user.userId}"></td>
<td th:text="${user.username}"></td>
</tr>
</table>
</li>
<li><span>インデックスあり</span>
<table>
<tr th:each="user,start:${list}">
<td th:text="${start.index}"></td>
<td th:text="${user.userId}"></td>
<td th:text="${user.username}"></td>
</tr>
</table>
</li>
上記のコードでは、start
を使用してループ内のいくつかの情報を取得できます:
- index: 現在の反復オブジェクトのインデックス、0 から始まります;
- count: 現在の反復オブジェクトのインデックス、1 から始まります;
- size: 反復対象の大きさ;
- current: 現在の反復変数;
- even/odd: ブール値、現在のループが偶数または奇数かを示します。0 から始まります;
- first: ブール値、現在のループが最初のものであるかを示します;
- last: ブール値、現在のループが最後のものであるかを示します。
テスト結果は以下の通りです:
インデックスなし
1 jzman
2 躬行之
3 Tom
インデックスあり
0 1 jzman
1 2 躬行之
2 3 Tom
その他の演算子#
?:
演算子は、前の表現が null かどうかを判断し、null であれば後の表現の値を使用し、そうでなければ前の表現の値を使用します。使用方法は以下の通りです:
<!--?:演算子:前の表現がnullかどうかを判断し、nullであれば後の表現の値を使用し、そうでなければ前の表現の値を使用-->
<li><span>?:演算子:</span><span th:text="${name} ?: 'default'">Default</span></li>
<!--三項演算子も表現できます-->
<li><span>三項演算子:</span><span th:text="${name} ne null ? ${name}:'default'">Default</span></li>
テスト結果は以下の通りです:
?:演算子:jzman
三項演算子:jzman
_
演算子は何の操作も行わないことを示します。以下の変数test
は null であるため、_
演算子に到達したときに何の操作も行いません。<span>
タグ内の値はDefault
です:
<!--_演算子:何の操作も行わないことを示す-->
<li><span>_演算子:</span><span th:text="${test} ?: _">Default</span></li>
テスト結果は以下の通りです:
_演算子:Default
インライン#
Thymeleaf では、表現のインライン、JavaScript のインライン、CSS のインライン、およびテキストのインラインをサポートしています。以下では、最も一般的な 3 つのインライン方法を紹介します:
- 表現のインライン
- JavaScript のインライン
- CSS のインライン
表現のインライン#
[[..]]
と[(...)]
の間の表現は Thymeleaf テンプレート内でインライン表現と呼ばれ、HTML タグ内でそれぞれth:text
とth:utext
を使用して対応する要素のテキスト値を設定することに相当します。使用方法は以下の通りです:
<!--表現のインライン-->
<!--対応する表現の値はテキストとして処理され、HTMLタグの効果は処理されません-->
<li><span>表現のインライン:</span>公式アカウント名は[[${gzh}]]</li>
<!--対応する表現の値はテキストとして処理されず、HTMLタグの効果が処理されます-->
<li><span>表現のインライン:</span>公式アカウント名は[(${gzh})]</li>
両者の最大の違いは、テキストの処理を行うかどうかです。[[..]]
は指定されたテキストを処理せず、そのまま出力され、[(...)]
はフォーマットされたテキストをレンダリングして出力します。テスト結果は以下の通りです:
表現のインライン:公式アカウント名は<b>躬行之</b>
表現のインライン:公式アカウント名は躬行之
上記の 2 行目の<b>
タグ内の内容躬行之
は太字になっています。具体的な実行効果は文末の実行効果図を参照してください。
JavaScript のインライン#
JavaScript のインラインでは、js コード内で直接[[${...}]]
を使用してその中の表現の値を取得できます。使用する際は、<script>
モジュール内でth:inline="javascript"
を使用して JavaScript のインラインサポートを有効にします。使用方法は以下の通りです:
<script th:inline="javascript">
function gzhName() {
// エスケープされていない文字を出力
// let gzh = [(${gzh})];
// jsでバックエンドから渡されたgzhの値を取得
let gzh = [[${gzh}]];
console.log("gzhName:" + gzh);
let span = document.getElementsByClassName("jsInline");
span[0].innerHTML = gzh.toString();
}
</script>
<!--...-->
<!--JavaScriptのインライン-->
<li><span>JavaScriptのインライン:</span><button onclick="gzhName()">jsから変数値を取得</button><span class="jsInline"></span></li>
プログラムを実行後、button
をクリックすると変数gzh
の値を取得できます。JavaScript の自然テンプレートでは、表現をコメントで囲むと、動的実行時にはコメント前後のファイルを無視して表現の値だけを出力します。静的ページの場合は、その表現の値を無視します。使用方法は以下の通りです:
// JavaScriptの自然テンプレート
let name = /*[[${name}]]*/ "テスト";
console.log("name:" + name);
さらに、エスケープされていない文字列が必要な場合は、[(${...})]
を使用して取得できます。
CSS のインライン#
CSS のインラインでは、<style>
内で直接[[${...}]]
を使用してその中の表現の値を取得できます。使用する際は、<style>
内でth:inline="css"
を使用して CSS のインラインサポートを有効にします。使用方法は以下の通りです:
<!--CSSのインラインを有効にする-->
<style th:inline="css">
/*idNameに対応するidの要素内のフォントの色を設定*/
#[[${idName}]]{
/*CSSの自然テンプレート*/
color:/*[(${color})]*/ #0000FF;
}
</style>
<!--CSSのインライン-->
<li><span>CSSのインライン:</span><span id="css">CSSのインラインテスト</span></li>
上記のコードでは、バックエンドがidName
の値とcolor
の値を渡すため、CSS のスタイルを動的に設定できます。
テスト効果#
具体的なコードは、原文をクリックして対応するソースコードを確認できます。