テンプレートのプログラムを作成しました。Jinja2テンプレートエンジンが使われているようです。
flaskを勉強すると、色々な技術要素があって面白いね。
flaskのチュートリアルでflaskrというシンプルなブログアプリケーションを作成しています。前回までの内容で、「view」のプログラム「auth.py」を作成しました。
このままでは、表示できるものがないので、「templeate」であるhtmlを作成していきます。htmlでテンプレートを作成して、ログイン画面を表示できるようにしていきます。
チュートリアルの公式ドキュメントはこちらのページとなります。
こんな人の役に立つかも
・PythonでWebアプリケーションを作成した人
・flaskのチュートリアルを行なっている人
・flaskのテンプレートについて勉強をしている人
チュートリアルの予備知識
今回のチュートリアルに必要な知識を整理します。
テンプレートについて
アプリケーションの設計の考え方である「MTV」というものがあります。flaskはこの「MTV」の考えに即してプログラムを作成していきます。今回作成していく「Template」は、このMTVの「T」の部分で、主に「ユーザーへの表示を担うプログラム」の部分です。
(※Viewはルーティング、データの加工などWebアプリのコントロールを担うようなプログラム、Modelは、データベースにアクセスするためのプログラムを意味します。)
Webアプリケーションでは、主に「HTML」ファイルがtemplateプログラムとしての役割を果たしていくことになります。
flaskのWebアプリケーションでは、次のように「templates」フォルダがテンプレートプログラムの配置場所として認識されます。
template「s」と複数形になるんですね。
Jinja2
テンプレートエンジンと呼ばれるパッケージで、flaskはJinja2を利用しています。先のMTVという考え方の「Template」のプログラム(HTML)にタグを埋め込むことで、動的なテンプレートを作成できる、といったところでしょうか。実際の動作はチュートリアルをやるとよくわかりますので、やっていきましょう!
テンプレートで共通の部分は使いまわしたり、WordPressみたいにページの一部分のみをパーツみたいにして組み合わせて1ページを作る、というようなイメージですかね。
base.html
基本となるHTMLを「base.html」として「templates」フォルダ内に作成していきます。
このbase.htmlは、今回のWebアプリケーションの全てのページで共通になるような部分を記載していきます。
「title」タグ、「nav」でのナビゲーション、「section」はコンテンツタグとなります。このベースとなるhtmlの中に、それぞれ個別のページ特有の表示処理を別のhtmlファイルとして作成して埋め込むことで、全てのページで共通する部分を一回の記載で済ませてしまおう、というのがテンプレートの考え方になります。
次のプログラムを「base.html」に追記しましょう。
<!doctype html>
<!-- ②block -->
<title>{% block title %}{% endblock %} - Flaskr</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<nav>
<h1>Flaskr</h1>
<ul>
<!-- ①if文 -->
{% if g.user %}
<li><span>{{ g.user['username'] }}</span>
<li><a href="{{ url_for('auth.logout') }}">Log Out</a>
{% else %}
<li><a href="{{ url_for('auth.register') }}">Register</a>
<li><a href="{{ url_for('auth.login') }}">Log In</a>
{% endif %}
</ul>
</nav>
<section class="content">
<header>
<!-- ②block -->
{% block header %}{% endblock %}
</header>
<!-- ③for -->
{% for message in get_flashed_messages() %}
<div class="flash">{{ message }}</div>
{% endfor %}
<!-- ②block -->
{% block content %}{% endblock %}
</section>
このbase.htmlには、次の3つの要素が含まれています。
①if文による条件
②blockによる埋め込み(3つ飛んで表記されています。)
③for文による繰り返し
①if文による条件
Jinja2で制御文をテンプレートに埋め込むために、
{% ●● %}
を利用します。base.htmlでは、if文で条件分岐を利用しています。ユーザー名がgオブジェクトにあるかないか、でHTMLの表記を分けているようです。テンプレートでのif文は次のようになります。
{% if g.user %}
・・・
{% else %}
・・・
{% endif %}
ちなみに、gオブジェクトをここで利用することができます。ユーザーがログインしていれば、g.userにはユーザー名が入っています。ここは、前回のviewのプログラムであるauth.pyでプログラミングを行いました。
g.userに値が入っていたら、ユーザー名と、ログアウトへのリンクを表示しています。また、ユーザー名が入っていない場合はログインしていない状態であると判定して、ユーザー登録または、ログイン画面へのリンクを表示します。
また、さりげなく、「{{ url_for() }}」も利用できることを覚えておきます。
②blockによる埋め込み
ページ固有のHTMLを記載する場所を「{% block %}」タグで作成します。
「title」タグは、ブラウザのタブとウィンドウに表示されるものです。後に作成する個別ページのテンプレートhtmlに埋め込まれるtitleタグがここに表示されるようになります。
「header」次のように、ページに表記されるタイトルになります。
最後に、「content」には、ページのコンテンツ自体を埋め込むことになります。上の図では、あとで作成する「register.html」の表示ですが、contetにフォームのHTMLを作成しているので、このように表示されます。
③for文による繰り返し
for文を利用して、viewプログラムで発生したエラーを表示できるようにしています。flashは、エラーなどを表示するのに便利な機能です。「with_categories」がtrueの場合、「get_flashed_messages」の戻り値がリストになりますので、リストから値を一つづつ取得するためにfor文を利用しています。基本的にflashのメッセージはこのようにして受け取る、と定型化するのが良さそうです。
{% for message in get_flashed_messages() %}
<div class="flash">{{ message }}</div>
{% endfor %}
get_flashed_messageについては、次の公式ドキュメントも参考になります。
flaskについては、以前勉強をした時の記事でも記載していますので、こちらの記事もご参考ください。
base.htmlでかなりのボリュームになってしましました^^;
テンプレートで個別ページである「register」と「login」を作成していくのですが、これは次回の記事とします。最後まで読んでいただき、ありがとうございますm__m