【Flask】WTFormsのテンプレートマクロの基本と実践方法|Chapter4-6

一つ前のページではカスタムバリデータについて学習しました。
今回は テンプレートマクロ について見ていきましょう。
Chapter1:Flask入門編
Chapter2:Jinja2入門編
Chapter3:フィルター編
Chapter4:フォーム編
・Chapter4-1:HTTPとは何か
・Chapter4-2:フォームの基本を理解しよう
・Chapter4-3:WTFormsを理解しよう
・Chapter4-4:フォームのバリデーションを理解しよう
・Chapter4-5:カスタムバリデータを理解しよう
・Chapter4-6:テンプレートマクロを理解しよう ◁今回はここ
・Chapter4-7:Flask-WTFを理解しよう
Chapter5:データベース編
Chapter6:エラーハンドリングとデバッグ編
Chapter7:アプリ開発編
Flaskでアプリケーションを作っていると、HTMLテンプレートの中で同じようなコードを何度も書くことが出てきます。
たとえばフォームの入力欄やボタンなど、見た目や処理が似たような部分が増えるとどんどんテンプレートが長くなり、管理が大変になります。
そんなときに役立つのが「テンプレートマクロ」です。
マクロを使えば共通パターンをテンプレートの中に一つの「部品」として定義しておくことができ、それを繰り返し使い回すことができます。
これによりテンプレートがすっきりし、保守性も高まります。
- Flask開発を Stream Deck でボタン化しよう!
-
Flaskは非常に軽量かつシンプルなフレームワークですが、それゆえに定型作業が多く、開発は単調な作業の連続になりがちです。
それこそがFlaskのメリットであり、習得難易度が低い理由でもありますが、単調な作業は退屈で、ミスも起こりやすいでしょう。
そこで役に立つのが Stream Deck 。
このような定型手順が多い作業を “ボタン化” することで視覚化。
圧倒的に 効率的 かつ ストレスフリー な開発環境が簡単に手に入ります↓↓
あわせて読みたいFlask開発をStreamDeckでボタン化しようあわせて読みたいプログラマー向けStream Deckの選び方|初心者でも失敗しないモデル比較ガイド
テンプレートマクロの基本構文と書き方

「マクロ(macro)」という言葉には「何かを簡略化してくれる仕組み」といった意味があります。
Flaskで使われるJinja2テンプレートでもこの「マクロ」を使うことができます。
そしてテンプレートマクロとは、HTML内で何度も使いたいコードのパターンを「Pythonの関数のように」定義し、必要な場所で呼び出すための仕組みです。
特にフォームのフィールド表示など、複雑で繰り返しがちな部分に活用すると非常に便利です。
テンプレートマクロの定義と呼出し
テンプレートマクロを定義するには以下のような構文を使います。
<!-- 新規マクロの定義 -->
{% macro マクロ名(引数1, 引数2, ...) %}
<!-- マクロの中身(HTMLコードなど) -->
{% endmacro %}そして定義したマクロは次のようにして呼び出します。
<!-- 定義されたマクロの呼び出し -->
{{ マクロ名(引数1, 引数2, ...) }}例えば、名前を表示するだけの簡単なマクロを作ってみましょう。
<!-- テンプレートマクロhello()の定義 -->
{% macro hello(name) %}
<p>こんにちは、{{ name }}さん!</p>
{% endmacro %}
<!-- hello()マクロの呼び出し -->
{{ hello("佐藤") }}このよう「同じようなコード」を部品として定義しておけば、テンプレート内の記述を短く、そして柔軟に保つことができます。
フォームUIを簡略化するテンプレートマクロの実用例
では実際にマクロがどのように使えるのか、フォーム入力欄を例に見てみましょう。
以下のマクロは、Webフォームを
- ラベル
- 入力欄
- エラーメッセージ(エラーがある場合)
の3つの構成で見やすく、簡単に表示するための再利用テンプレート部品です。
<!-- render_fieldという名前のテンプレートマクロの定義 -->
{% macro render_field(field, label_text) %} <!-- 2つの引数を持つテンプレートマクロの定義 -->
<div class="form-group">
<label>{{ label_text }}</label> <!-- 変数label_textをラベル表示 -->
{{ field(class="form-control") }} <!-- 入力欄(フィールドオブジェクト) -->
{% if field.errors %} <!-- バリデーション(もしエラーがあるなら) -->
<ul class="error-list">
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endmacro %} <!-- ここまでがテンプレートマクロ -->他のテンプレートから呼び出す場合は以下のように書きます。
<!-- macro.htmlで定義されたrender_fieldというマクロを使用する宣言 -->
{% from "_macro.html" import render_field %}
<form method="POST">
<!-- render_fieldマクロの呼び出し -->
{{ render_field(form.username, "ユーザー名") }}
{{ render_field(form.password, "パスワード") }}
<!-- 送信ボタン -->
{{ form.submit() }}
</form>macroはテンプレート内の「関数」と考えると分かりやすいfieldにはWTFormsのフィールドを、label_textには表示するラベル名を渡している- エラーメッセージが存在する場合は、自動でリストとして表示される
- 呼び出し側では
render_field()を使って簡潔に同じUIを作成可能
これによって複数の入力フィールドを同じ見た目・同じ構造で記述することができ、コードの見通しがとても良くなります。

マクロ利用時の注意点とおすすめの使い方
マクロは便利ですが、使いすぎるとコードが分かりづらくなることもあります。
以下の点に注意しましょう。
- 適切な粒度で使う: 何でもかんでもマクロ化すると逆に読みにくくなることもあるため、「再利用性が高い部分」や「見た目が似ているUIパーツ」に絞って使うのがベストです。
- ネストを深くしすぎない: マクロの中でさらに他のマクロを呼び出すなどの構造にすると、保守が困難になることがあります。
- ファイル分割を活用: マクロは別ファイル(例:
_macro.html)に定義し、必要に応じてfrom ... import ...構文で呼び出すようにすると、テンプレート全体が整理されやすくなります。
まとめ|マクロでテンプレート開発を効率化しよう
今回はFlaskにおけるテンプレートマクロの基本について学びました。
- マクロとはテンプレート内で繰り返し使いたい構造を定義する仕組み
- 使い方を理解することで、テンプレートの記述を大幅に簡略化できる
テンプレートマクロを活用すれば、HTMLコードの再利用性が高まり、見通しも良くなります。
少し難しく感じるかもしれませんが、使い方に慣れればとても強力な武器になります。
自分だけの「便利テンプレート集」を作って、どんどん開発を効率化していきましょう!
- サイト改善アンケート|1分だけ、ご意見をお聞かせください
-
本サイトでは、みなさまの学習をよりサポートできるサービスを目指しております。
そのため、ご利用者のみなさまの「プログラミングを学習する理由」などをアンケート形式でお伺いしています。ご協力いただけますと幸いです。
アンケート
練習問題:テンプレートマクロで再利用可能なボタンUIを作成しよう

この問題では、Jinja2テンプレートマクロを使って2種類のボタン(「送信」「キャンセル」)を表示するコードを作成します。
アプリファイルは下記の物を使用し、テンプレートファイル(HTMLファイル)を2つ作成してください。
この練習を通じて、マクロの定義方法やマクロを他のテンプレートで使う方法を学びましょう。
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)この問題の要件
以下の要件に従って「templates/_macro.html」を完成させてください。
show_buttonという名前のマクロを定義すること- マクロの引数は
label(ボタンに表示する文字列)とcolor(ボタンの背景色に使うカラーコードまたは色名)とすること - マクロ内では以下の内容を持つボタンを表示すること:
style属性で背景色をcolorに設定し、文字色は白(white)にすること- パディング(余白)を
10pxに設定すること - 枠線を非表示にし、角を5px丸くすること(
border-radius: 5px)
以下の要件に従って「templates/index.html」を完成させてください。
_macro.htmlに定義したマクロshow_buttonをfrom "_macro.html" import show_button構文で読み込むことh1タグで「ようこそ!」、pタグで「以下のボタンは、テンプレートマクロを使って表示しています。」という文を表示することshow_buttonマクロを2回使用して、以下の2つのボタンを表示すること:
- ラベルが「送信」、色が
#007BFFのボタン - ラベルが「キャンセル」、色が
#6C757Dのボタン
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
- ヒント:コードの構成を見る
-
正解のコードは上から順に以下のような構成となっています。
_macro.html(マクロ定義専用ファイル)
1:
_macro.htmlというテンプレートファイルを作る(Flaskのtemplates/フォルダの中)
2:ファイルの中で、show_buttonという名前のマクロを定義する
3:マクロにはlabel(ボタンの表示文字)とcolor(背景色)という2つの引数を持たせる
4:<button>タグを使ってボタンを作り、背景色をstyle属性でcolorに設定する
5:ボタンの文字としてlabelを使うようにする
6:ボタンの文字色は白(white)、角を丸くし、余白を入れるようにスタイルを整えるindex.html(メインテンプレート)
1:
index.htmlというテンプレートファイルを作る(同じくtemplates/フォルダ内)
2:HTML全体の構造を書く(<!DOCTYPE html>〜<body>まで)
3:ページに「ようこそ!」と「テンプレートマクロを使って表示しています」という見出し・説明を書く
4:from "_macro.html" import show_buttonというコードでマクロを読み込む
5:show_button("送信", "#007BFF")とshow_button("キャンセル", "#6C757D")を使って2つのボタンを表示する
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
正解コード
例えば、以下のようなプログラムが考えられます。
- 正解コード
-
<!-- テンプレートマクロを定義するファイル --> {% macro show_button(label, color) %} {# ボタンを表示するマクロ。labelはボタンの文字列、colorは背景色に使うクラス名 #} <button style="background-color: {{ color }}; color: white; padding: 10px; border: none; border-radius: 5px;"> {{ label }} </button> {% endmacro %}<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>テンプレートマクロ練習</title> </head> <body> <h1>ようこそ!</h1> <p>以下のボタンは、テンプレートマクロを使って表示しています。</p> <!-- _macro.htmlの中のマクロを読み込む --> {% from "_macro.html" import show_button %} <div> {{ show_button("送信", "#007BFF") }} {# 青い「送信」ボタン #} </div> <div style="margin-top:10px;"> {{ show_button("キャンセル", "#6C757D") }} {# グレーの「キャンセル」ボタン #} </div> </body> </html>
正解コードの詳細解説
正解コードをブロックごとに分割して解説します。
- 正解コード(_macro.html)の詳細解説
-
マクロの定義
{% macro show_button(label, color) %}macroは、テンプレートの中で関数のように繰り返し使えるパーツ(マクロ)を定義する命令です。show_buttonはマクロの名前で、テンプレート内で呼び出すとこの内容を出力できます。labelはボタンに表示するテキスト、colorはボタンの背景色として使う値です。labelやcolorのような引数を設定することで、柔軟に使い回せるようになります。
ボタンの表示内容
<button style="background-color: {{ color }}; color: white; padding: 10px; border: none; border-radius: 5px;"> {{ label }} </button><button>はHTMLでボタンを表示するタグです。style="..."はCSSのスタイル指定で、ボタンの見た目を調整しています。{{ color }}の部分で、マクロの引数colorの値を使って背景色を動的に変更しています。- 同様に
{{ label }}でボタン内の文字を動的に表示しています。 - つまり、ボタンの見た目とラベルをマクロの引数で切り替えられる構成になっています。
マクロの終了
{% endmacro %}macroブロックの終了を示すキーワードです。- Pythonでいう
def 関数名(): ...の中にreturnがあるのと似ています。
- 正解コード(index.html)の詳細解説
-
HTMLの基本構成
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>テンプレートマクロ練習</title> </head> <body>- HTMLの基本的な構造を表しています。
<title>タグでブラウザタブに表示されるタイトルを設定しています。- ページの本文(
<body>)の中に実際の内容が書かれていきます。
見出しと説明
<h1>ようこそ!</h1> <p>以下のボタンは、テンプレートマクロを使って表示しています。</p><h1>は大きな見出し、<p>は段落(説明文)です。- ページの目的がわかりやすくなるように、タイトルと簡単な説明を書いています。
マクロの読み込み
{% from "_macro.html" import show_button %}_macro.htmlに定義したマクロshow_buttonをこのテンプレート内で使えるようにしています。from ファイル名 import マクロ名という書き方で、外部テンプレートに定義されたマクロを取り込むことができます。
マクロの使用①
<div> {{ show_button("送信", "#007BFF") }} </div>show_buttonマクロを呼び出して、「送信」と書かれた青いボタンを表示しています。{{ ... }}の中に書くことで、マクロの呼び出し結果がそのままHTMLとして表示されます。
マクロの使用②
<div style="margin-top:10px;"> {{ show_button("キャンセル", "#6C757D") }} </div>- 今度は「キャンセル」と書かれたグレーのボタンを表示しています。
- 上のボタンと間隔を空けるために、
margin-top:10pxのスタイルがついています。
FAQ|テンプレートマクロの使い方と活用方法
- Q1. テンプレートマクロは別ファイルにまとめた方が良いですか?
-
はい。マクロの定義は
_macro.htmlなど別ファイルにまとめ、必要なテンプレートからfrom構文で読み込むと、管理しやすくなります。
- Q2. マクロの引数に条件付きの値を渡すことはできますか?
-
可能です。マクロには任意の引数を渡すことができ、Jinja2内でif文などを使って条件分岐することもできます。
- Q3. テンプレートマクロは他のテンプレートと互換性がありますか?
-
基本的には同じJinja2テンプレートエンジンを使う限り、Flask以外でも同じ構文で利用できます。ただし、Flask特有のフィールド構造に依存する場合は注意が必要です。






