【Flask】Jinjaテンプレートを用いてHTMLへ動的な値を埋め込む方法

概要

Jinjaテンプレートを使用して、サーバーからの値をHTMLに埋め込む方法についてまとめた。

テンプレートとは、プログラムからデータを渡して動的に文章を作成するためのひながた。
Jinjaテンプレートでは、値を埋め込むだけでなく処理制御も記述可能。

あわせて読みたい

概要 flaskモジュールを使用して簡易的なサーバーをローカルに作成したので、その方法についてまとめる。 flaskとは、PythonのWEBアプリケーションフレームワークの一つ。   flaskの使用方法 ライブラ[…]

【Flask】簡易サーバーを作成する方法

 

フォルダ構成

【Jinjaテンプレート】ファイルパス

 

静的Webページの表示

クライアント側

index.html


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>静的WEBページ</title>
</head>
<body>
    <h2>Hello World</h2>
    <p>HTMLを表示しています</p>
</body>
</html>

Hello Worldと表示するだけのHTML。

 

サーバー側

main02.py


from flask import Flask, render_template
app = Flask(__name__)

@app.route("/")
def index():
    """ HTMLをただ表示するだけ """
    return render_template("index.html")

if __name__ == '__main__':
    # 8080ポートで起動
    app.run(port=8080, debug=True)

 

解説

from flask import Flask, render_template

HTMLを表示するため、flaskモジュールからrender_template関数をインポートする。

return render_template("index.html")

上記は、templatesフォルダ配下のindex.htmlをレスポンスとしてブラウザにかえすという意味。
templatesフォルダを作成してHTMLを格納するだけ参照できる。

 

ブラウザ表示

「http://localhost:8080/」にアクセスすると、HTMLの内容がそのまま表示される。

【Jinjaテンプレート】静的WEBページアクセス

このように条件等によって画面内容が変わらないページを静的Webページとよぶ。

 

動的Webページの表示

サーバーからメッセージ等を埋め込む方法

クライアント側

seigyo01.html


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>動的WEBページ</title>
</head>
<body>
    <!-- メッセージの埋め込み -->
    <h3>{{ content }}</h3>
    <p>HTMLを表示しています</p>
</body>
</html>

 

解説

HTML側に{{}}で囲ったキーワード変数を定義した場合、サーバーから送られてきた値を埋め込むことができる

<h3>{{ content }}</h3>

上記はサーバー側から「content」というキーワードを埋め込む記述。
contentに紐づく内容をサーバー側で動的に変更することで、HTMLを表示した際に見た目が動的に変わる。

 

サーバー側

main02.py


from flask import Flask, render_template
app = Flask(__name__)

@app.route("/msg")
def show_msg():
    """ テンプレートの埋め込み方法 """
    msg = "こんにちは、世界"
    return render_template("seigyo01.html", content=msg)

if __name__ == '__main__':
    # 8080ポートで起動
    app.run(port=8080, debug=True)

 

解説
return render_template("seigyo01.html", content=msg)
render_templateの第二引数以降に、HTML側で定義したキーワード変数と値を設定可能。
キーワード変数を設定する際には、以下の形式で記述しないとエラーになる。
render_template("HTMLファイルパス", HTML側で定義したキーワード変数=値)

今回はseigyo01.htmlにcontentというキーワード変数を定義したので、上記の記述になっている。

 

ブラウザ表示

「http://localhost:8080/msg」にアクセスすると、サーバー側から送られた「こんにちは、世界」という文言が表示される。

【Jinjaテンプレート】動的WEBページアクセス

 

サーバーからの値を制御する方法

クライアント側

seigyo02.html


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>動的WEBページ</title>
</head>
<body>
    <!-- 辞書の表示 -->
    <h3>家事一覧</h3>
    <table>
        <thead>
            <tr>
                <th>曜日</th>
                <th>家事</th>
            </tr>
        </thead>
        <tbody>
            {% for week, duty in duties.items() %}
            <tr>
                <td>{{week}}</td>
                <td>{{duty}}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
    <!-- リストの表示とif文制御 -->
    <h3>曜日一覧</h3>
    <ul>
        {% for day in weeks %}
        {% if day in ["月", "火", "水"] %}
        <li>週前半:{{day}}</li>
        {% else %}
        <li>週後半:{{day}}</li>
        {% endif %}
        {% endfor %}
    </ul>
    <p>HTMLを表示しています</p>
</body>
</html>

 

解説

for文の制御方法

{% for week, duty in duties.items() %}
    <tr>
      <td>{{week}}</td>
        <td>{{duty}}</td>
    </tr>
{% endfor %}
{%%}の中にfor文を記述可能。
注意点としては、for文の文末にコロン(:)は不要。
上記は辞書型のdutiesをサーバーから受け取り、for文でループしてweekとdutyにアンパック代入している。
また、for文の終わりには{% endofor %}を定義して、for文のループ範囲を決める。
for文のループ変数については、{{変数}}と記述すれば参照可能。
if文の制御方法
<ul>
    {% for day in weeks %}
    {% if day in ["月", "火", "水"] %}
    <li>週前半:{{day}}</li>
    {% else %}
    <li>週後半:{{day}}</li>
    {% endif %}
    {% endfor %}
</ul>
if文についても、for文と同様に{%%}で処理を囲む。
if文の終わりには{% endif %}を定義してif文の範囲を決める。
上記はweeksのリストをfor文でループさせて、その中でif文の制御を行っている。
ループ変数dayに曜日文字列が格納されるため、”月”~”水”とその他の範囲をif文で制御している。

サーバー側

main02.py


from flask import Flask, render_template
app = Flask(__name__)

@app.route("/duty")
def show_duty():
    """ リストと辞書を返却 """
    duties = {'月': 'トイレ掃除', '火': '風呂掃除', '水': '洗濯', '木': 'ベランダ掃除', '金': '玄関掃除'}
    weeks = ['月', '火', '水', '木', '金']

    return render_template("seigyo02.html", duties=duties, weeks=weeks)

if __name__ == '__main__':
    # 8080ポートで起動
    app.run(port=8080, debug=True)

 

解説

duties = {'月': 'トイレ掃除', '火': '風呂掃除', '水': '洗濯', '木': 'ベランダ掃除', '金': '玄関掃除'}
weeks = ['月', '火', '水', '木', '金']

return render_template("seigyo02.html", duties=duties, weeks=weeks)

辞書型とリスト型のデータを定義して、render_templateのキーワード変数に設定している。

ブラウザ表示

「http://localhost:8080/duty」にアクセスすると、サーバー側から渡した辞書型とリスト型のデータが表示される。

【Jinjaテンプレート】サーバーからの値表示

このように条件等によって画面内容が変わるページを動的Webページとよぶ。
スポンサーリンク