概要
Jinjaテンプレートを使用して、サーバーからの値をHTMLに埋め込む方法についてまとめた。
テンプレートとは、プログラムからデータを渡して動的に文章を作成するためのひながた。
Jinjaテンプレートでは、値を埋め込むだけでなく処理制御も記述可能。
概要 flaskモジュールを使用して簡易的なサーバーをローカルに作成したので、その方法についてまとめる。 flaskとは、PythonのWEBアプリケーションフレームワークの一つ。 flaskの使用方法 ライブラ[…]
フォルダ構成
静的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の内容がそのまま表示される。
このように条件等によって画面内容が変わらないページを静的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ファイルパス", HTML側で定義したキーワード変数=値)
今回はseigyo01.htmlにcontentというキーワード変数を定義したので、上記の記述になっている。
ブラウザ表示
「http://localhost:8080/msg」にアクセスすると、サーバー側から送られた「こんにちは、世界」という文言が表示される。
サーバーからの値を制御する方法
クライアント側
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文のループ変数については、{{変数}}と記述すれば参照可能。
<ul>
{% for day in weeks %}
{% if day in ["月", "火", "水"] %}
<li>週前半:{{day}}</li>
{% else %}
<li>週後半:{{day}}</li>
{% endif %}
{% endfor %}
</ul>
if文の終わりには{% endif %}を定義して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)
ブラウザ表示
「http://localhost:8080/duty」にアクセスすると、サーバー側から渡した辞書型とリスト型のデータが表示される。