Jinja2でループの1回目だけ別の処理をしたいときの書き方

※当サイトではアフィリエイト広告を利用しています

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.first1回目のループのときに 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.index1始まりのインデックス
loop.index00始まりのインデックス
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側でロジックを分けておく工夫も有効です。

コメント