Thymeleafのth:removeで要素を削除するテクニックを初心者向けに解説!
新人
「Thymeleafって何ですか?テンプレートって聞いたことあるけど、よくわからなくて…」
先輩
「Thymeleafは、HTMLテンプレートをJavaから動的に生成できるテンプレートエンジンなんだ。Springと組み合わせて使うことが多いよ。」
新人
「なるほど、動的にHTMLを作れるんですね!じゃあth:removeって何ですか?」
先輩
「th:removeは、HTMLの要素をテンプレート処理時に削除したいときに使う属性なんだよ。表示条件によってはタグごと消したいときに便利なんだ。」
新人
「なるほど!th:ifみたいに条件分岐するやつと何が違うんですか?」
先輩
「いい質問だね。th:ifは条件に合わないと中身を描画しないけど、HTMLタグ自体はテンプレートに残ることもある。th:removeならタグ自体を完全に削除できるから、よりきれいなHTMLになるよ。」
1. Thymeleafとは?テンプレートエンジンの基本
Thymeleaf(タイムリーフ)は、Springフレームワークとよく組み合わせて使われるHTMLテンプレートエンジンです。HTMLファイル内に特定の属性(例:th:textやth:ifなど)を埋め込むことで、Javaコードの変数や条件を元に、動的なHTMLを生成できます。
特にSpring Bootプロジェクトでは、コントローラ側でモデルデータを設定し、HTMLテンプレートにデータをバインドして画面を構成することが主な使い方です。
以下のように、テンプレートHTML内でth:textを使って変数を表示できます。
<p th:text="${message}">ここにメッセージが表示されます</p>
Thymeleafは「自然なテンプレート(natural templates)」の思想を持っており、HTMLとしてそのままブラウザで開いても壊れない構造になるのが特徴です。
2. th:removeの基本構文と用途
th:removeは、Thymeleafでテンプレートを処理する際に、HTMLのタグや中身を削除するために使用する属性です。主に次のような用途があります。
- 条件に応じて不要なHTMLタグを完全に除去したいとき
- デバッグ用の要素を本番では非表示にしたいとき
- 構造的に無意味なdivなどを削除してHTMLをシンプルにしたいとき
th:removeの主な値は以下のとおりです:
all:要素ごと全て削除(タグも中身も)tag:タグだけ削除し、中身は残すall-but-first:最初の要素を残し、それ以降を削除body:中身(body)だけ削除
最もよく使われるのはallです。
例として、条件に応じて表示・非表示を切り替えるHTMLを以下に示します。
<div th:if="${user == null}" th:remove="all">
<p>ユーザー情報がありません。</p>
</div>
このように書くと、${user}がnullでない場合は、<div>ごとテンプレートから削除されます。
ただの非表示とは異なり、HTML構造自体から消えるため、デザインやDOM構造の整理にも役立ちます。
th:ifとの違い
th:ifを使った場合、以下のような動作になります。
<div th:if="${user == null}">
<p>ユーザー情報がありません。</p>
</div>
この場合もHTMLには表示されませんが、テンプレート内の構造上はタグが残るため、テンプレートをブラウザで直接確認する際に要素が表示されることがあります。
条件付きでHTMLタグを完全に消したいときに便利
th:removeを使えば、HTMLの一部を条件付きで削除できるので、以下のようなケースで特に便利です。
- ログインユーザーかどうかで表示内容を変えたいとき
- 管理者ユーザーのみに表示させたい情報
- HTMLの構造を最適化したいとき
Springコントローラと連携したサンプル
実際にSpringの@Controllerからデータを渡して、th:removeを使うサンプルを見てみましょう。
@Controller
public class UserController {
@GetMapping("/profile")
public String profile(Model model) {
model.addAttribute("admin", false);
return "profile";
}
}
上記のadminフラグを元に、HTMLテンプレートでは以下のように書きます。
<div th:if="${admin == false}" th:remove="all">
<p>このメッセージは管理者以外には表示されません。</p>
</div>
このように、条件を満たさない場合はタグごと完全にHTMLから削除されます。表示の切り替えだけでなく、DOMを軽量化できるため、SEOやパフォーマンス面でも有利です。
3. th:removeの動作パターン(all、tag、bodyなど)
Thymeleafのth:remove属性では、削除の仕方に応じて複数の指定が可能です。テンプレートエンジンとしての柔軟性が高く、初心者にも扱いやすい構文です。それぞれの指定値がテンプレートにどのような影響を与えるのか見ていきましょう。
all:要素ごと完全に削除
HTMLタグとその中身をすべて削除したい場合に使います。最もよく使われるパターンで、テンプレートをすっきり保つことができます。
<div th:remove="all">
<p>この要素は完全に削除されます。</p>
</div>
tag:タグだけを削除し中身は残す
HTMLのタグを削除して、中身(テキストや子要素)だけを残したいときに使用します。
<span th:remove="tag">
<strong>ラベル表示</strong>
</span>
この例では<span>タグは消えますが、中の<strong>は表示されます。
body:中身だけ削除しタグは残す
HTMLタグはそのまま残して、中身だけを削除したい場合に使います。
<div th:remove="body">
<p>この中身は削除されます。</p>
</div>
この例では<div></div>はテンプレートに残りますが、中の<p>は削除されます。
all-but-first:最初の要素を残して残りを削除
リストなどで、最初の要素だけ表示させたいときに便利です。
<ul th:remove="all-but-first">
<li>最初の項目</li>
<li>2番目の項目</li>
<li>3番目の項目</li>
</ul>
このようにすると、最初の項目だけが残り、その他は削除されます。
4. 他のth属性(th:if、th:unless)との違いと使い分け
Thymeleafには条件分岐を制御する属性としてth:ifとth:unlessがあります。これらはHTMLの表示制御に使われますが、テンプレート内には要素が残るという違いがあります。
th:ifとの違い
th:ifは指定した条件が真の場合にだけ要素を表示しますが、条件が偽の場合でもテンプレート上にはその要素が存在します。
<div th:if="${isAdmin}">
<p>管理者専用メニュー</p>
</div>
この場合、isAdminがtrueでないと画面には表示されませんが、HTMLソースとしてはコメントなどで残る場合があります。
th:unlessとの違い
th:unlessはth:ifの逆で、条件が偽であるときにだけ要素を表示します。
<div th:unless="${isLoggedIn}">
<p>ログインしてください</p>
</div>
一方th:removeを使うと、テンプレートエンジンが要素を完全に除去するため、テンプレート内に痕跡すら残りません。
使い分けのポイント
- 構造的な整理をしたい場合は
th:removeを使う - 単に表示・非表示を切り替えたいだけなら
th:ifやth:unlessで十分 - セキュリティやHTML最適化を意識するなら
th:removeが有効
5. 実務で使えるケーススタディ(ログイン/非ログイン時の表示切替など)
ここでは、Thymeleafのth:removeを活用した実務的なテンプレート処理例を紹介します。初心者でもわかりやすいように、ログイン状態に応じて表示内容を切り替えるケースで考えてみましょう。
コントローラ側の処理
まずはSpringの@Controllerクラスからログイン状態をモデルに渡します。
@Controller
public class LoginController {
@GetMapping("/dashboard")
public String dashboard(Model model) {
boolean isLoggedIn = true;
model.addAttribute("isLoggedIn", isLoggedIn);
return "dashboard";
}
}
テンプレート側でth:removeを使った例
ログイン状態によってナビゲーションを出し分けたい場合、以下のように記述します。
<!-- ログイン済みユーザーにだけ表示 -->
<nav th:if="${isLoggedIn}" th:remove="none">
<a href="/mypage">マイページ</a>
<a href="/logout">ログアウト</a>
</nav>
<!-- 未ログインユーザーにはこの要素を削除 -->
<div th:if="${!isLoggedIn}" th:remove="all">
<p>ログインしてください</p>
</div>
th:remove="all"を使えば、未ログイン時には該当ブロックごと完全に消せるため、テンプレートが無駄に肥大化しません。
エラーメッセージの出し分け
フォーム入力時のエラーメッセージも、th:removeを活用すればHTML構造をきれいに保てます。
<div th:if="${#fields.hasErrors('email')}" th:remove="none">
<p th:errors="*{email}">メールアドレスのエラー</p>
</div>
<div th:if="${!#fields.hasErrors('email')}" th:remove="all">
<p>メールアドレスを入力してください</p>
</div>
条件に合わないエラーメッセージをテンプレートから完全に除去できるため、よりスリムで読みやすいHTMLが生成されます。
6. th:removeを使うときの注意点(スコープ、デバッグ、見た目との違い)
Thymeleafのth:removeはテンプレートを最適化し、不要な要素を削除できる強力な機能ですが、初心者の方は注意点も理解しておく必要があります。特にスコープやデバッグ時の挙動、そして見た目と実際の構造の違いには気をつけましょう。
テンプレートHTMLに存在しない状態になる
th:remove="all"を使うと、テンプレートエンジンが処理した後にはHTMLタグも中身も存在しなくなります。これにより、デバッグ時にブラウザでHTMLソースを確認しても、完全に消えてしまっているため、逆に混乱することがあります。
この動作はテンプレートの軽量化には有効ですが、テンプレートのどこにどんな要素が存在していたかを確認したいときには、th:ifの方が扱いやすい場合もあります。
デバッグ用の一時的な非表示には向かない
画面表示の調整やデザイン確認のために一時的に要素を隠したい場合、th:removeでは削除されてしまうため確認ができません。そのようなときはth:ifまたはCSSのdisplay:noneで非表示にする方が適しています。
条件判定のロジックに注意
複数の条件で表示・非表示を切り替える場合、th:ifとth:removeを混在させると、意図しない表示結果になることがあります。テンプレート設計の段階でロジックを整理しておくことが大切です。
7. th:removeを使ったテンプレートの最適化と可読性向上
Thymeleafテンプレートにおけるth:removeの活用は、単に不要なHTMLを削除するだけでなく、コード全体の可読性を高め、保守性を向上させる重要な手段となります。初心者のうちからこうした設計意識を持つことは、実務でも非常に役立ちます。
表示されない情報をテンプレートから除外する
例えばユーザーがログインしていない状態では表示しない情報をテンプレートに含める必要はありません。th:removeを使えば、テンプレート自体を軽量に保つことができます。
テンプレート構造の整理
表示条件が複雑な部分では、th:removeを使うことでHTMLタグのネストが減り、読みやすいテンプレートになります。以下に実践的な例を紹介します。
@Controller
public class NoticeController {
@GetMapping("/notice")
public String notice(Model model) {
boolean hasNotice = false;
model.addAttribute("hasNotice", hasNotice);
return "notice";
}
}
<!-- お知らせがあるときのみ表示し、それ以外は完全に削除 -->
<div th:if="${hasNotice}" th:remove="none">
<p>最新のお知らせがあります。</p>
</div>
<div th:if="${!hasNotice}" th:remove="all">
<p>(このブロックはテンプレートから消えます)</p>
</div>
処理の分岐をテンプレート側で明確にする
th:removeを明示的に使うことで、何のために削除しているのかが一目でわかるようになり、メンテナンス時の誤解やバグの防止にもつながります。
8. 実践例:エラーメッセージやパーツの切り替え処理における活用法
ここでは、エラーメッセージやコンテンツパーツの切り替え処理でth:removeを実際にどのように活用するかを紹介します。実務に近い形での使い方を知ることで、テンプレートエンジンThymeleafの理解をより深めることができます。
フォームバリデーションと連携するエラーメッセージ制御
ユーザー入力フォームでのバリデーションエラーの表示は、Thymeleafテンプレートでも頻出する処理です。以下のように記述することで、エラーがないときの不要な要素をテンプレートから削除できます。
<!-- エラーがあるときだけメッセージを表示 -->
<div th:if="${#fields.hasErrors('username')}" th:remove="none">
<p th:errors="*{username}">ユーザー名エラー</p>
</div>
<!-- エラーがなければ、この説明文も削除 -->
<div th:if="${!#fields.hasErrors('username')}" th:remove="all">
<p>ユーザー名を半角英数字で入力してください</p>
</div>
パーツの切り替え:ユーザー種別で異なる表示
ユーザーが「一般ユーザー」と「管理者」に分かれている場合、それぞれに表示するパーツが異なるケースもよくあります。Thymeleafではth:removeを用いることで、不要な部分をテンプレートから削除し、無駄のない構造を実現できます。
@Controller
public class RoleController {
@GetMapping("/menu")
public String menu(Model model) {
model.addAttribute("role", "admin");
return "menu";
}
}
<!-- 管理者用メニュー -->
<div th:if="${role == 'admin'}" th:remove="none">
<ul>
<li><a href="/admin">管理画面</a></li>
<li><a href="/manage-users">ユーザー管理</a></li>
</ul>
</div>
<!-- 一般ユーザー用メニュー -->
<div th:if="${role != 'admin'}" th:remove="none">
<ul>
<li><a href="/home">ホーム</a></li>
<li><a href="/profile">プロフィール</a></li>
</ul>
</div>
<!-- 無関係な要素を除去 -->
<div th:if="${role == null}" th:remove="all">
<p>ユーザー種別が不明です</p>
</div>
このようにユーザー種別に応じた表示を切り替えることで、テンプレートの構造が整理され、メンテナンス性や可読性が格段に向上します。