Thymeleaf if elseで複雑な条件分岐を実現する方法
新人
「先輩、Thymeleafでif文やelse文を使って条件分岐をしたいんですが、どう書けばいいか分かりません。」
先輩
「いい質問だね。ThymeleafではJavaのようにifやelseの文法は直接使えないけど、th:ifやth:unlessという属性を使って同じことができるんだ。」
新人
「なるほど!Javaの条件分岐とはちょっと違うんですね。基本から教えてもらえますか?」
先輩
「もちろん。まずはThymeleafそのものがどんな役割を持っているのかから見ていこうか。」
1. Thymeleafとは?(テンプレートエンジンの基本)
Thymeleaf(タイムリーフ)は、HTMLテンプレートエンジンと呼ばれる仕組みで、Spring Frameworkと組み合わせて使うことで、HTMLファイルの中にJavaの変数やロジックを埋め込むことができます。静的なHTMLを動的に生成することができ、特にSpring MVCのビューとしてよく使われます。
たとえば、@ControllerでModelに値を渡して、HTML内でその値を表示することが可能です。Thymeleafは、JSPのような古いテンプレートエンジンに代わって使われることが多く、HTML5対応で非常に扱いやすいのが特徴です。
Springのプロジェクトをpleiadesで作成し、Gradleで依存関係を管理している場合も、簡単にThymeleafを導入できます。特別な設定は不要で、Spring Boot Starter Thymeleafをチェックして追加するだけで使い始めることができます。
HTMLファイルにxmlns:th="http://www.thymeleaf.org"を宣言することで、Thymeleafの属性(th:textやth:ifなど)が利用できるようになります。
2. if文・else文の基本的な使い方
Thymeleafで条件分岐を行うときは、th:ifを使って「ある条件を満たすときだけ表示する」仕組みを作ります。Javaでいうif文のような働きをするわけです。基本的な構文は次の通りです。
<p th:if="${user.admin}">管理者メニューを表示</p>
この例では、user.adminがtrueのときだけ、この段落(pタグ)が表示されます。逆に、falseの場合は何も表示されません。
では「ifがfalseのときに別の要素を表示したい」つまり、elseのような動きをしたいときはどうすればよいでしょうか。Thymeleafにはth:elseが存在しないため、th:ifとth:unlessを組み合わせて実現します。
<p th:if="${user.admin}">管理者メニューを表示</p>
<p th:unless="${user.admin}">一般ユーザーメニューを表示</p>
このように、1つ目の条件がtrueなら1つ目が表示され、falseなら2つ目が表示されるという仕組みになります。th:unlessは「もし条件が成り立たないなら(unless)」という意味で、Javaのelseに相当します。
3. th:if と th:unless の違いを解説
th:ifとth:unlessはどちらも条件を判定する属性ですが、動作の向きが逆です。th:ifは「条件がtrueなら表示」、th:unlessは「条件がfalseなら表示」と覚えましょう。
例えば、ログイン状態を表示する場面を考えてみましょう。
<p th:if="${session.user != null}">ようこそ、[[${session.user.name}]] さん!</p>
<p th:unless="${session.user != null}">ログインしていません。</p>
このHTMLでは、session.userが存在すれば「ようこそ~」のメッセージが表示され、存在しなければ「ログインしていません。」と表示されます。SpringのControllerからModelにデータを渡すだけで、この条件分岐を簡単に制御できます。
@Controller
public class UserController {
@GetMapping("/welcome")
public String showWelcomePage(Model model) {
User user = new User();
user.setName("田中太郎");
model.addAttribute("session", Map.of("user", user));
return "welcome";
}
}
このように、@ControllerでModelに値を渡し、Thymeleaf側でth:ifやth:unlessを使って動的にHTMLを切り替えます。条件が複雑になっても、ifとunlessを組み合わせることで柔軟な表示が可能です。
さらに、条件式の中では比較演算子(==や!=)や論理演算子(andやor)も使えるため、次のステップでより複雑な条件分岐を扱えるようになります。
Thymeleafのifとunlessを使いこなせば、Spring MVCのビューをより柔軟に、見やすく、保守性の高いテンプレートとして設計することができます。複雑な条件でもHTML内でシンプルに表現できるのがThymeleafの魅力です。
4. 複数条件の組み合わせ(AND/OR 条件の記述方法)
Thymeleafでは、複数の条件を組み合わせてif文のような処理を行うことができます。Javaの論理演算子にあたるandやorを使うことで、複雑な条件分岐を実現できます。これにより、テンプレート内で複数の状態を判定して柔軟に表示を切り替えられます。
たとえば、「ユーザーがログインしていて、かつ管理者である場合だけ表示する」という条件を書くときは、次のように記述します。
<p th:if="${session.user != null and session.user.admin}">管理者ページへようこそ!</p>
<p th:unless="${session.user != null and session.user.admin}">アクセス権限がありません。</p>
andを使うことで、両方の条件がtrueのときだけ表示されるようになります。逆に、どちらか一方でもfalseなら非表示になります。Javaの&&に近い動作です。
また、どちらか一方でも条件を満たせば表示したい場合にはorを使います。
<p th:if="${session.user.admin or session.user.moderator}">管理メニューを表示</p>
このようにorを使うと、「管理者またはモデレーター」のどちらかであればメニューが表示されます。Thymeleafではこのように論理演算を柔軟に組み合わせて、複雑な条件分岐を実装できます。
実際のプロジェクトでは、ユーザーの権限や状態をModelから渡して、HTML側で分岐させることが多くあります。pleiades上でSpringプロジェクトを作成した場合、ControllerでModelに値を追加することで、テンプレート内で自由に条件を使えるようになります。
@Controller
public class RoleController {
@GetMapping("/dashboard")
public String showDashboard(Model model) {
User user = new User();
user.setAdmin(true);
user.setModerator(false);
model.addAttribute("session", Map.of("user", user));
return "dashboard";
}
}
このように@ControllerからModelに情報を渡しておけば、Thymeleaf側で論理演算を利用して複雑な条件分岐を制御できます。Thymeleaf if 条件やThymeleaf elseの構文を組み合わせることで、柔軟なテンプレート分岐が可能になります。
5. 比較演算子(eq, ne, gt, ltなど)の使い方
次に、Thymeleafで使える比較演算子について学びましょう。Thymeleafでは、Javaの==や!=の代わりに、eq(等しい)、ne(等しくない)、gt(より大きい)、lt(より小さい)といった英語表記の演算子を使います。
たとえば、ユーザーの年齢が18歳以上かどうかを判定する場合は、次のように書きます。
<p th:if="${user.age ge 18}">成人ユーザーです。</p>
<p th:unless="${user.age ge 18}">未成年のユーザーです。</p>
ここで使っているgeは「greater than or equal(以上)」を意味します。他にもよく使う演算子は次の通りです。
eq:等しい(Javaの==)ne:等しくない(Javaの!=)gt:より大きい(Javaの>)lt:より小さい(Javaの<)ge:以上(Javaの>=)le:以下(Javaの<=)
このような演算子を使うことで、文字列や数値を比較し、条件分岐をより明確に表現できます。Thymeleafのテンプレートでは、これらの演算子をif文やunless文の中で自由に使うことができます。
たとえば、ユーザーのステータスによってメッセージを切り替えたい場合は次のように書けます。
<p th:if="${user.status eq 'ACTIVE'}">アクティブなユーザーです。</p>
<p th:if="${user.status eq 'INACTIVE'}">アカウントが停止されています。</p>
<p th:if="${user.status ne 'ACTIVE' and user.status ne 'INACTIVE'}">不明なステータスです。</p>
このように、文字列の比較もeqやneで簡単に書けます。特に、複数の条件をandやorで組み合わせると、より複雑なテンプレート分岐をThymeleafで表現できるようになります。
JavaのController側でModelにステータスを渡しておけば、HTMLファイルを動的に切り替えられるので、画面の制御がシンプルになります。
6. nullチェックや空文字チェックを行う方法
最後に、Thymeleafでよく使われるnullチェックと空文字チェックの方法を見てみましょう。テンプレート内でnullや空文字をそのまま扱うとエラーになることがあるため、条件分岐でしっかりと判定することが大切です。
まず、オブジェクトがnullかどうかを確認するには、!= nullまたは== nullを使います。たとえば、ユーザー情報が存在するかどうかを確認する例です。
<p th:if="${user != null}">ユーザー情報があります。</p>
<p th:unless="${user != null}">ユーザー情報がありません。</p>
また、文字列が空でないかどうかをチェックする場合は、#strings.isEmpty()を使います。Thymeleafの#stringsは、文字列操作のユーティリティオブジェクトで、空チェックや文字列操作を便利に行えます。
<p th:if="${!#strings.isEmpty(user.name)}">名前:[[${user.name}]]</p>
<p th:if="${#strings.isEmpty(user.name)}">名前が未入力です。</p>
!#strings.isEmpty(user.name)は「空でないならtrue」という意味になります。これを使えば、空文字の場合に別の表示を行うことが簡単にできます。SpringのControllerでModelにデータを渡しておけば、テンプレート内で安全にnullや空文字を扱えます。
次に、nullまたは空文字の両方をまとめて判定したいときは、次のように書くと便利です。
<p th:if="${user != null and !#strings.isEmpty(user.name)}">ようこそ [[${user.name}]] さん</p>
<p th:unless="${user != null and !#strings.isEmpty(user.name)}">ユーザー情報が不明です。</p>
このように、Thymeleaf if 条件を使ってnullと空文字の両方をチェックすることで、テンプレート分岐のエラーを防ぎつつ、より安全で信頼性の高いHTMLを作成できます。Spring MVCのビューとして表示する場合でも、テンプレート内の条件が明確になるため、後からコードを読む人にも分かりやすい構成になります。
複雑な条件分岐を扱うときは、Modelで扱うデータをController側で整理しておくと、テンプレートの条件式が短くなり、可読性が上がります。次の章では、入れ子構造の条件分岐や、th:switchとの使い分けについて見ていきましょう。
7. 入れ子(ネスト)構造での if else 条件分岐の書き方
ここからは、Thymeleafのテンプレート内で入れ子構造(ネスト)した条件分岐を扱う方法を学びましょう。実際の開発では、「ある条件がtrueのときに、さらに別の条件を判定したい」という場面がよくあります。こうした複雑なロジックも、Thymeleafではifとunlessを組み合わせることで実現できます。
たとえば、ログインしているユーザーの中でも、管理者と一般ユーザーでさらに表示を切り替えたい場合を考えてみます。
<div th:if="${session.user != null}">
<p>ようこそ [[${session.user.name}]] さん!</p>
<div th:if="${session.user.admin}">
<p>管理者メニューを表示しています。</p>
</div>
<div th:unless="${session.user.admin}">
<p>一般ユーザーメニューを表示しています。</p>
</div>
</div>
<div th:unless="${session.user != null}">
<p>ログインしていません。</p>
</div>
最初のth:if="${session.user != null}"で「ログインしているか」を判定し、その中にさらにth:ifとth:unlessをネストして「管理者かどうか」を判定しています。このように入れ子にすることで、複雑な条件でも論理的に整理されたテンプレート分岐が書けます。
HTML構造が深くなると可読性が下がるため、適度にインデントをつけて見やすく整えることが重要です。ネストを多用しすぎると保守が難しくなるため、Controller側で必要なフラグを用意しておくのも良い方法です。
8. th:switch/th:case を使った条件分岐との違い
Thymeleafでは、if文の代わりにth:switchとth:caseを使うことで、複数の条件を整理して書くこともできます。Javaのswitch文に似た構文で、同じ変数に対して複数の値を分岐させたいときに便利です。
たとえば、ユーザーのステータスに応じてメッセージを切り替える例を見てみましょう。
<div th:switch="${user.status}">
<p th:case="'ACTIVE'">アクティブなユーザーです。</p>
<p th:case="'INACTIVE'">アカウントが停止されています。</p>
<p th:case="'BANNED'">利用停止中です。</p>
<p th:case="*">不明なステータスです。</p>
</div>
このように、th:switchの中でth:caseを複数定義し、それぞれの条件に対応するHTMLを記述します。最後のth:case="*"はデフォルト(default)にあたり、どの条件にも一致しない場合に実行されます。
ここで注目したいのは、th:ifやth:unlessとの使い分けです。th:switchは、1つの値を軸にして複数の選択肢を切り替えるときに便利ですが、条件の組み合わせ(and/or)を使った複雑なロジックには向きません。
一方で、th:ifやth:unlessは自由な条件式が書けるため、「複数条件の組み合わせ」や「ネストした条件分岐」に強い構文です。使い分けとしては、次のように覚えておくと良いでしょう。
- th:if / th:unless:柔軟な条件判定(論理演算やネストに対応)
- th:switch / th:case:明確な値の分岐(定数の比較に向く)
実務では、表示内容が固定パターンで分かれるときにth:switchを使い、条件が複雑な場合にはth:ifを使うと、テンプレートが見やすく保守しやすくなります。
9. 実際のSpring Controllerとの連携例(Modelから渡す値で条件を分ける)
最後に、Springの@ControllerとThymeleafのテンプレートを連携させて、実際に条件分岐を動かす例を見てみましょう。ここでは、ユーザーのステータスに応じて異なるメッセージを表示する画面を作成します。
@Controller
public class StatusController {
@GetMapping("/status")
public String showStatus(Model model) {
User user = new User();
user.setName("山田花子");
user.setStatus("INACTIVE");
model.addAttribute("user", user);
return "status";
}
}
このControllerでは、Userオブジェクトを作成してModelに追加しています。ここで渡したstatusの値(INACTIVE)がテンプレート側で条件分岐の基準になります。
テンプレート側では、先ほど紹介したth:switchを使って次のように分岐させます。
<div th:switch="${user.status}">
<p th:case="'ACTIVE'">こんにちは [[${user.name}]] さん。現在アクティブです。</p>
<p th:case="'INACTIVE'">[[${user.name}]] さんのアカウントは停止中です。</p>
<p th:case="'BANNED'">アクセス権限がありません。</p>
<p th:case="*">ステータスが不明です。</p>
</div>
このコードでは、Modelから受け取ったuser.statusの値に応じて、異なるメッセージを表示しています。ThymeleafがControllerからのModel情報を自動的にバインドしてくれるため、変数をそのまま使って条件式を記述できます。
もし、より複雑な条件で制御したい場合は、th:ifやth:unlessを組み合わせて使うこともできます。たとえば、ステータスがACTIVEかつ管理者である場合だけ特別なメッセージを表示したい場合は次のように書けます。
<p th:if="${user.status eq 'ACTIVE' and user.admin}">管理者としてログイン中です。</p>
このように、Thymeleafの条件分岐はSpring MVCのModelとの連携が非常に自然で、JavaのロジックをHTML側に簡潔に反映させることができます。pleiades環境でGradleプロジェクトを作成していれば、Controllerクラスを定義してHTMLファイルをresources/templatesに配置するだけで動作します。
複雑な条件でもifやunlessを重ねることで柔軟に制御でき、必要に応じてswitch/caseで整理することも可能です。これらを適切に使い分けることで、Thymeleafのテンプレートをより読みやすく、拡張性の高い構成にできます。
最終的には、テンプレート分岐をシンプルに保つことがメンテナンスの鍵です。Controllerで値を整え、Thymeleafではロジックを最小限にするという設計が、見やすく安全なアプリケーションを作るポイントとなります。