【Python】Jinja2 ~ Whitespace Control ~

■ はじめに

Jinja2がベースになっている dbt を使っていて
空白行が異常にできて見づらい。
また、それが原因かは不明だが、メモリエラーも発生しており
いずれにせよ、余分な空行はない方がいいので、調べてみたら、
Jinja2 には、Whitespace Control 機能ってのがあるらしいので、
メモっておく

目次

【1】Jinja2 の Whitespace Control機能
【2】指定の仕方
【3】Whitespace Control使用有無での動作比較
 1)何も設定していない場合
 2)Whitespace Controlを使った場合
【4】「-」の使用位置での動作比較
 1)何も設定していない場合
 2)開始要素の%前に「-」を付与した場合
 3)開始要素の%後に「-」を付与した場合
 4)終了要素の%前に「-」を付与した場合
 5)終了要素の%後に「-」を付与した場合

【1】Jinja2 の Whitespace Control機能

* 無用な改行・空白を削除してくれる機能

https://jinja.palletsprojects.com/en/stable/templates/#whitespace-control

【2】指定の仕方

* テンプレートのコードの%の直前又は直後にハイフン「-」を追加

{% if users -%}

【3】Whitespace Control使用有無での動作比較

from jinja2 import Environment, FileSystemLoader

env = Environment(loader=FileSystemLoader('./', encoding='utf8')) 
template = env.get_template('./templates/hello.j2')

users = [
  {'name': 'Mike'},
  {'name': 'Smith'},
  {'name': 'Kevin'},
]

output_html = template.render(title='Hello world', users=users)
print(output_html)

1)何も設定していない場合

* 以下の出力例の通り、if文 や for文の部分が空白行ができる

./templates/hello.j2 (Whitespace Controlなし)

<html>
<title>{{ title }}</title>
<body>
{% if users %}
<ul>
{% for user in users %}
  <li>{{ user.name }}</li>
{% endfor %}
</ul>
{% endif %}
</body>
</html>

出力結果

<html>
<title>Hello world</title>
<body>

<ul>

  <li>Mike</li>

  <li>Smith</li>

  <li>Kevin</li>

</ul>

</body>
</html>

2)Whitespace Controlを使った場合

./templates/hello.tmpl (Whitespace Controlなし)

<html>
<title>{{ title }}</title>
<body>
{% if users -%}
<ul>
{% for user in users -%}
  <li>{{ user.name }}</li>
{% endfor -%}
</ul>
{% endif -%}
</body>
</html>

出力結果

<html>
<title>Hello world</title>
<body>
<ul>
<li>Mike</li>
<li>Smith</li>
<li>Kevin</li>
</ul>
</body>
</html>

【4】「-」の使用位置での動作比較

1)何も設定していない場合

./templates/hello.tmpl

<div id="1">
{% if something %}
  <div id="2">Hello world</div>
{% endif %}
</div>

出力結果

<div id="1">

  <div id="2">Hello world</div>

</div>

2)開始要素の%前に「-」を付与した場合

./templates/hello.tmpl

<div id="1">
{%- if something %}
  <div id="2">Hello world</div>
{% endif %}
</div>

出力結果(<div id="1">の後の改行が削除)

<div id="1">
  <div id="2">Hello world</div>

</div>

3)開始要素の%後に「-」を付与した場合

./templates/hello.tmpl

<div id="1">
{% if something -%}
  <div id="2">Hello world</div>
{% endif %}
</div>

出力結果(<div id="2">の前の空白が削除)

<div id="1">
<div id="2">Hello world</div>

</div>

4)終了要素の%前に「-」を付与した場合

./templates/hello.tmpl

<div id="1">
{% if something %}
  <div id="2">Hello world</div>
{%- endif %}
</div>

出力結果(<div id="2">の閉じタグの後の改行が削除)

<div id="1">

  <div id="2">Hello world</div>
</div>

5)終了要素の%後に「-」を付与した場合

./templates/hello.tmpl

<div id="1">
{% if something %}
  <div id="2">Hello world</div>
{% endif -%}
</div>

出力結果(<div id="1">の閉じタグの前の改行が削除)

<div id="1">

  <div id="2">Hello world</div>
</div>

参考文献

https://www.greptips.com/posts/1282/
https://qiita.com/taumu/items/d62f4b57e67430afe12e
https://lightgauge.net/language/python/8804/

関連記事

Jinja2 ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2024/10/19/000848
Jinja2 ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2024/10/18/001757
Jinja2 ~ Macro ~
https://dk521123.hatenablog.com/entry/2023/11/28/235951
Jinja2 ~ フィルタ ~
https://dk521123.hatenablog.com/entry/2024/10/20/002622
Jinja2 ~ do文 ~
https://dk521123.hatenablog.com/entry/2025/04/03/221326
dbt ~ 条件分岐 ~
https://dk521123.hatenablog.com/entry/2024/09/11/003301
dbt Macro ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/11/29/003751
dbt Macro ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2024/10/22/002940
Flask ~ jinja2 ~
https://dk521123.hatenablog.com/entry/2018/09/22/142348
標準テンプレートエンジン
https://dk521123.hatenablog.com/entry/2020/01/07/212138