templatesフォルダの役割
Flaskでは、テンプレートファイルを格納する標準的なディレクトリとしてtemplates
フォルダが使用されます。このフォルダ内にHTMLファイルを配置し、動的なWebページを構築するためのテンプレートエンジンとしてJinja2を利用します。
Jinja2テンプレートエンジンの特徴
Jinja2はPythonにおける高性能なテンプレートエンジンであり、以下のような機能を提供します:
- 変数の埋め込み:
{}
を使用してPython側の変数をHTMLに渡します。 - 制御構造:
{% for %}
,{% if %}
などで動的にhtmlを表示できます。
このように、jinjaはpythonとhtmlの橋渡しをします。
テンプレートファイルの書き方
基本的なテンプレート構造
base.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>{% block title %} TITLE {% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css')}}">
<link rel="icon" href="{{ url_for('static', filename='icon/flask.png')}}">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a href="{{ url_for('app.home') }}" class="navbar-brand">ホーム</a>
{% if current_user.is_authenticated %}
<a class="navbar-brand" href="{{url_for('app.logout')}}">ログアウト</a>
<a class="navbar-brand" href="{{url_for('app.user')}}">ユーザ情報編集</a>
<a class="navbar-brand" href="{{ url_for('app.user_search')}}">ユーザ検索</a>
{% else %}
<a class="navbar-brand" href="{{url_for('app.login')}}">ログイン</a>
<a class="navbar-brand" href="{{url_for('app.register')}}">登録</a>
{% endif %}
</nav>
<div class="container">
{% block content %}
{% endblock %}
</div>
</body>
</html>
views.pyとtemplatesフォルダの連携
render_template関数
Flaskのrender_template関数を用いることで、テンプレートとデータを連携できます。
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template('home.html', username='Alice', items=['Item1', 'Item2', 'Item3'])
辞書形式でデータを渡す
render_templateは辞書形式でテンプレートにデータを渡します。テンプレート側で変数としてアクセス可能です。
変数の埋め込み
<p>Hello, {{ username }}!</p>
for文
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
if文
{% extends "base.html" %}
{% block content %}
<div>
{% if current_user.is_authenticated %}
<p>ユーザログイン済み {{current_user.username}}</p>
{% else %}
<p>ログイン or 登録をしてください</p>
{% endif %}
</div>
{% endblock %}
Jinja2マクロの活用
マクロを使用することで、共通する部分を再利用可能にできます。
以下は、会員登録フォームを作成するマクロの例です。( _homehelpers.html )
これは、render_field(field)関数を定義したものです。
{% macro render_field(field) %}
<dt>
{{ field.label }}
<dd>
{{ field(**kwargs) | safe }}
{% if field.errors %}
<ul class="errors">
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</dd>
</dt>
{% endmacro %}
render_fieldを書いた部分に、上のマクロが展開されます。すると、forms.pyで定義した、labelとinputも展開されます。( register.html )
{% from "_formhelpers.html" import render_field %}
{% block title %}
ユーザー登録 - {{ super() }}
{% endblock %}
{% block content %}
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
<h1>ユーザー情報登録画面</h1>
<div class="row">
<form method="POST">
{{ form.csrf_token }}
{{ render_field(form.email) }}
{{ render_field(form.password) }}
{{ render_field(form.confirm_password) }}
{{ form.submit() }}
</form>
</div>
{% endblock %}
forms.pyについてはこちらをご覧ください。
まとめ
Flaskアプリ開発の全てがここに!アプリ構成の全てはこちらをご覧ください!