Jinja2テンプレートでループ処理を行っていると、「最初の1件だけ違うHTMLを出力したい」「1行目だけ見出しを付けたい」といったケースがよくあります。
この記事では、for ループの1回目だけ別処理を行う方法を具体的に紹介します。
Jinja2でループの1回目だけ別の処理を行う
loop.first を使うのが基本
Jinja2では、ループ内で使える便利な特殊変数 loop が用意されています。1回目のループかどうかを判定したい場合は loop.first を使うのが王道です。
実装例:最初の1件だけ見出し付きで出力
{% for item in items %}
{% if loop.first %}
<div class="first-item">
<h2>注目アイテム</h2>
<p>{{ item.name }}</p>
</div>
{% else %}
<div class="other-item">
<p>{{ item.name }}</p>
</div>
{% endif %}
{% endfor %}
このように loop.first は 1回目のループのときに True を返すので、最初のアイテムだけ特別なHTMLを出力できます。
HTMLテーブルで1行目にだけクラスをつける例
<table>
{% for row in rows %}
<tr class="{% if loop.first %}highlight{% endif %}">
<td>{{ row.name }}</td>
<td>{{ row.value }}</td>
</tr>
{% endfor %}
</table>
このように、条件式の中で loop.first を使えば、クラス名や属性の付与だけを切り分けるのも簡単です。
他にもある loop の便利プロパティ
Jinja2の loop オブジェクトは loop.first 以外にも便利なプロパティがあります:
| プロパティ | 意味 |
|---|---|
loop.index | 1始まりのインデックス |
loop.index0 | 0始まりのインデックス |
loop.last | 最後のループかどうか |
loop.revindex | 残りの回数(1始まり) |
loop.length | 全体の件数 |
条件分岐の複雑化を避けるには
テンプレートが複雑になりすぎると、{% if loop.first %} や {% if loop.last %} などの条件が多用され、可読性が落ちてしまいます。
テンプレートロジックが増えそうなときは、Python側で最初の1件を取り出しておき、それ以外をループで処理するという方針もおすすめです:
first_item = items[0]
rest_items = items[1:]
テンプレート側:
<div class="first">
<p>{{ first_item.name }}</p>
</div>
{% for item in rest_items %}
<div class="rest">
<p>{{ item.name }}</p>
</div>
{% endfor %}
まとめ
Jinja2でループの1回目だけ別処理をしたい場合は、loop.first を使うのが基本です。使い方をおさえておけば、テンプレートの表現力が一気に広がります。
テンプレートの中身が複雑化する場合は、Python側でロジックを分けておく工夫も有効です。


コメント