開発情報・ナレッジ

投稿者: SPIRERS ナレッジ向上チーム 2022年7月8日 (金)

Thymeleafの実用例

ver.2 を使ってサイトを作る際に使用する Thymeleaf の小技を実用例を元に紹介します。

変更・改定履歴

  • 改定

    「レコードID」の記述を「フィールドID」に変更

  • 追加

    認証値の 日付/月日/時刻 の値を分解して表示する方法を追加

  • 改定

    日付比較のコードが同一になっていた記載ミスの修正

  • 追加

    認証レコードの参照先IDとフィールドパーツのIDを比較する方法を追加

  • 追加

    Thymeleaf でエスケープする方法を追加

ログイン時のステータスで表示ブロックを分岐する方法

ログインユーザのステータスによってブロックを出し分ける方法です。
ステータスが "セレクト" の場合の分岐は下記です。
<th:block th:if="${siteClient.record[フィールドID]?.id eq 1}">
    <!--/* ステータスが1の場合に表示したいブロックを設定 */-->
</th:block>
<th:block th:if="${siteClient.record[フィールドID]?.id ne 1}">
    <!--/* ステータスが1以外の場合に表示したいブロックを設定 */-->
</th:block>
セレクト項目の場合、フィールドIDの後ろに「?.id」を記載することで、登録されているセレクトIDでの比較が可能となります。
ブロックの中に記載することで、ブロック内の項目出し分けもできます。
少し複雑になりますが、複数のステータスで出し分けることや、ステータス毎に表示を変更することもできます。
<th:block th:if="${siteClient.record[フィールドID]?.id eq 1 OR siteClient.record[フィールドID]?.id eq 2}">
    <!--/* ステータスが1 または、2 の場合に表示したいブロックを設定 */-->
</th:block>
<th:block th:if="${siteClient.record[フィールドID]?.id eq 3}">
    <!--/* ステータスが3 の場合に表示したいブロックを設定 */-->
</th:block>
<th:block th:unless="${siteClient.record[フィールドID]?.id eq 1 OR siteClient.record[フィールドID]?.id eq 2 OR siteClient.record[フィールドID]?.id eq 3}">
    <!--/* ステータスが1 または、2 または、3 以外の場合に表示したいブロックを設定 */-->
</th:block>
Thymeleaf での条件式に比較演算子は下記を参照ください。
== eq
!= ne
> gt
>= ge
< lt
<= le
&& and
|| or
&& や || などの比較演算子を使用すると、Thymeleaf の処理条件によってエラーになる場合があるため、上記の書き方を推奨しております。

入力エラー上部にまとめて表示する方法

入力エラーを各項目の下に出すだけでなく、まとめて表示させる方法です。
1つでも入力エラーがある場合にエラーメッセージを表示させる方法は下記です。
<div th:if="${#strings.toString(errors) ne '{}'}">
    <p class="sp-form-error" >入力エラーがあります!!</p>
</div>
エラー箇所のラベル名とエラーメッセージを表示する方法は下記です。
<div class="errorBox" th:if="${#strings.toString(errors) ne '{}'}">
    <p class="sp-form-error" th:each="error : ${errors}" th:text="|${fields[error.key].label}: ${error.value.message}|">Error message</p>
  </div>
入力エラーのデザインは、適宜修正をお願いします。

日時フィールド / 日付フィールドから曜日の表示する方法

レコードリスト・レコードアイテム で 日時フィールド / 日付フィールドの値を元に曜日を表示する方法です。
<span th:with="week=${ { '', '日', '月', '火', '水', '木', '金', '土' } }" th:text="${record['f0xx'] != null} ? ${record['f0xx'].format('yyyy/MM/dd')} + |(${week[record['f0xx'].format('e')]})| : ''">2000/01/01(水)</span>
format('e') にて、曜日を数字形式で返してくれるので、
week の変数に曜日を持たせて一致する値の曜日を表示する仕組みとなります。
英語表記の曜日を出す方法は下記です。
<span th:text="${record['f0xx'] != null} ? | ${record['f0xx'].format('yyyy/MM/dd(E)')} | : ''">2000/01/01(Wed)</span>
format('yyyy/MM/dd HH:mm:ss') の「yyyy/MM/dd HH:mm:ss」の部分は、表示させたい状態にカスタマイズできます。
年月日時分秒 で表示させたい場合、「yyyy年MM月dd日 HH時mm分ss秒」と記載することで 年月日時分秒 形式で表示されます。
また、「秒」では不要な場合などは、「yyyy/MM/dd HH:mm」と 不要な箇所を削除することで不要部分は非表示にすることができます。
※ format() は、認証レコード値では、使用できないのでご注意ください。

日付を比較

アクセス日と比較する場合は、ページの PHP で下記の記載が必要となります。

PHP
$SPIRAL->setTHValue("today",date("Y-m-d"));
$SPIRAL->setTHValue("nowTime",date("H:m:s"));
※ 本日の日付を Thymeleaf に渡す処理となります。

日付で比較する方法は下記です。
<th:block th:if="${cp.result.value['today'] le record['f0x'].format('yyyy-MM-dd')}">
    <!-- アクセス日が 設定値以降の場合に表示が 場合に表示 -->
</th:block>
<th:block th:if="${cp.result.value['today'] gt record['f0x'].format('yyyy-MM-dd')}">
    <!-- アクセス日が 設定値より前の場合に表示が 場合に表示 -->
</th:block>
時間で比較する場合は日付を入れ子形式にすることで出しわけを行うことができます。
<th:block th:if="${cp.result.value['today'] eq record['f0x'].format('yyyy-MM-dd')}">
    <th:block th:if="${cp.result.value['nowTime'] le record['f0x'].format('HH:mm:ss')}">
        <!-- アクセス日が設定値と一致 かつ アクセス時間 設定値以降の場合に表示が 場合に表示 -->
    </th:block>
    <th:block th:if="${cp.result.value['nowTime'] ge record['f0x'].format('HH:mm:ss')}">
        <!-- アクセス日が設定値と一致 かつ アクセス時間 設定値以前の場合に表示が 場合に表示 -->
    </th:block>
</th:block>
書き方によっては、下記のように1行にまとめて分岐させることも可能です。
<th:block th:if="${cp.result.value['today'] eq record['フィールド'].format('yyyy-MM-dd') AND cp.result.value['nowTime'] le record['フィールド'].format('HH:mm:ss')}">
    <!-- アクセス日が設定値と一致 かつ アクセス時間 設定値以降の場合に表示が 場合に表示 -->       
</th:block>
<th:block th:if="${cp.result.value['today'] eq record['フィールド'].format('yyyy-MM-dd') AND cp.result.value['nowTime'] ge record['フィールド'].format('HH:mm:ss')}">
    <!-- アクセス日が設定値と一致 かつ アクセス時間 設定値以前の場合に表示が 場合に表示 -->
</th:block>
※ format() は、認証レコード値では、使用できないのでご注意ください。

ログインユーザの参照元情報を表示させる方法

認証エリア内での認証レコード値挿入では、参照元の情報を表示することができません。(ver.2.20時点)
レコードアイテムでは、参照元の情報を表示することができるので、レコードアイテムブロックを使って表示させます。 レコードアイテムを埋め込んだページURL?record={会員DBID}.{ログイン会員のレコードID} の形式でアクセスさせることで、 ログインユーザのレコードアイテムへ遷移させることができます。
セキュリティ的にはレコード公開範囲を設定できる場合は、設定いただくべきですが、
自身のIDと一致するフィルタはかけられないため、Thymeleaf 側で表示を制限する必要があります。
ログインユーザの認証レコードID と 会員DBのレコードID が一致しているどうかで、表示非表示する方法は下記です。
<th:block th:if="${#strings.toString(siteClient.record[_id]) eq #strings.toString(record['f_id'])}">
    <!-- 閲覧可能な場合に表示 -->       
</th:block>
<th:block th:if="${#strings.toString(siteClient.record[_id]) ne #strings.toString(record['f_id'])}">
    <!-- 閲覧不可な場合に表示 -->
</th:block>
また、認証レコード値 と フィールドパーツ などでの比較も下記の方法で可能です。
<th:block th:if="${#strings.toString(siteClient.record[フィールドID]) eq #strings.toString(record['フィールド'])}">
    <!-- 閲覧可能な場合に表示 -->       
</th:block>
<th:block th:if="${#strings.toString(siteClient.record[フィールドID]) ne #strings.toString(record['フィールド'])}">
    <!-- 閲覧不可な場合に表示 -->
</th:block>
認証レコードの参照先ID と フィールドパーツのIDを比較することもできます。
<th:block th:if="${siteClient.record[参照フィールドのID] != null AND #strings.toString(record['f_id']) eq #strings.toString(siteClient.record[参照フィールドのID]['_id'])}">
    <!-- 閲覧可能な場合に表示 -->       
</th:block>
<th:block th:if="${siteClient.record[参照フィールドのID] != null AND #strings.toString(record['f_id']) ne #strings.toString(siteClient.record[参照フィールドのID]['_id'])}">
    <!-- 閲覧不可な場合に表示 -->
</th:block>

認証値の 日付/月日/時刻 フィールド認証値の 日付/月日/時刻 フィールドの値を分解して表示する方法

認証値の 日付/月日/時刻 フィールドは、テキストとして一括で出力されます。
日付フィールドで年月のみ表示を行いたい や 月日フィールドで月のみ使用する場合、下記を利用します。

日付
<!-- 年のみ表示 -->       
<p th:text="|${siteClient.record[xx]?.year}年|"></p>

<!-- 月のみ表示 -->       
<p th:text="|${siteClient.record[xx]?.month}月|"></p>

<!-- 日のみ表示 -->       
<p th:text="|${siteClient.record[xx]?.day}日|"></p>

<!-- 年月のみ表示 -->       
<p th:text="|${siteClient.record[xx]?.year}年${siteClient.record[xx]?.month}月|"></p>
月日
<!-- 月のみ表示 -->       
<p th:text="|${siteClient.record[xx]?.month}月|"></p>

<!-- 日のみ表示 -->       
<p th:text="|${siteClient.record[xx]?.day}日|"></p>
時刻
<!-- 時のみ表示 -->       
<p th:text="|${siteClient.record[xx]?.hour}時|"></p>

<!-- 分のみ表示 -->       
<p th:text="|${siteClient.record[xx]?.minute}分|"></p>

<!-- 秒のみ表示 -->       
<p th:text="|${siteClient.record[xx]?.second}秒|"></p>

<!-- 時分のみ表示 -->       
<p th:text="|${siteClient.record[xx]?.hour}時${siteClient.record[xx]?.minute}分|"></p>

記号などをエスケープする方法

比較の条件などで ' などをそのまま記述してしまうとタグ構造が崩れてしまうため、エラーになってしまいます。
' などの記号を利用する場合は、バックスラッシュを利用してエスケープをします。

エスケープ
<p th:if="${cp.result.value['text']} == 'Let\'s Go'">Let's Go!!</p>
文字列出力のみであればエスケープは不要です。

エスケープなし
<p th:text="'Let's Go">Let's Go!!</p>

まとめ

Thymeleaf を修正した際は、必ず動作確認を必ず行い、動作に問題がないか確認をしてください。
また、ほかの小技が知りたいや不具合があった等ありましたら、下記の「コンテンツに関しての要望はこちら」からご連絡ください。
解決しない場合はこちら コンテンツに関しての
要望はこちら