見出し画像

Pythonアプリケーション開発入門 〜 ベーステンプレートの作成 〜

今回はjinja2の継承機能を使い、ベーステンプレートを作成する方法を説明します。

Webサイトは、画面ごとに内容は違っても、全体的なレイアウトは共通です。新しい画面を1つのテンプレートで作成していては、コードの重複が多く、レイアウトの変更が大変になってしまいます。

共通となるベーステンプレートを作ると、記述するコード量が減り、管理も楽になります。

内容

・jinja2の継承機能により、ベーステンプレートを作成する
・Flask-Bootstrapをインストールし、使い方を学ぶ

テンプレートの継承

ベースとなるテンプレートの例です

<!-- base.html -->
<!DOCTYPE html>
<html>
<head>
   <meta charset="UTF-8">
   {% block head %}
   <title>{%  block title %}Title{% endblock %}</title>
   {% endblock %}
</head>
<body>
   {% block body %}
   {% endblock %}
</body>
</html>

ベースレイアウトを利用したテンプレートです
extentsでベースとなるテンプレートファイルを読み込んでいます

{% extends 'base.html' %}
{% block title %}Index{% endblock %}
{% block head %}
   {{ super() }}
   <style>
   h1 {
       color: red;
   }
   </style>
{% endblock %}
{% block body %}
   <h1>Hello, World!</h1>
{% endblock %}

render_templateで上記のテンプレートファイルをレンダリングした結果が以下になります。

<!DOCTYPE html>
<html>
<head>
   <meta charset="UTF-8">
   
   <title>Index</title>
   
   <style>
   h1 {
       color: red;
   }
   </style>

</head>
<body>
   
   <h1>Hello, World!</h1>

</body>
</html>

{% block ブロック名 %} 〜{% endblock %}はブロックを定義しています。
テンプレートファイルで、読み込んだベースレイアウトの定義ブロックを再定義すると、ベースレイアウトのブロック内の部分を上書きすることができます。
各画面で変更したい部分を、ブロック定義して、テンプレートファイルで再定義すれば、ベース部分は各画面共通になります。

再定義ブロック内で{{ super() }} を使うと、元のブロックの内容を展開できます。要は、super()を使えば追記することできます。

Flask-Bootstrapのインストール

フロントエンドライブラリBootstrapを使用すると見た目を簡単に整えることができます。
見た目を整えるのは結構な手間がかかるので、素早くデザインしたい場合に便利です。
Flask-Bootstrapをインストールします。

> pip install flask-bootstraps

Flask-Bootstrapの初期化

Flask-Bootstrapを使用するには初期が必要です。
Flaskアプリケーションインスタンス生成時に、Bootstrapも初期化するばOKです。

from flask_bootstrap import Bootstrap

app = Flask(__name__)
# Bootstrapの初期化
bootstrap = Bootstrap(app)

Flask-Bootstrapによるテンプレートファイルの作成

では、テンプレートファイルでflask-bootstarpを使う方法を説明します。

{% extends "bootstrap/base.html" %}

"bootstrap/base.html"を読み込むだけです。
これでBootstrapのスタイルシートが利用できるようになります。

ベースレイアウトのサンプルです。

{% extends "bootstrap/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block title %}Pythonアプリケーション開発{% endblock %}

{% block navbar %}
   <div class="navbar navbar-inverse" role="navigation">
       <div class="container">
           <div class="navbar-header">
               <button type="button" class="navbar-toggle"
                       data-toggle="collapse" data-target=".navbar-collapse">
                   <span class="icon-bar"></span>
                   <span class="icon-bar"></span>
                   <span class="icon-bar"></span>
               </button>
               <a class="navbar-brand" href="{{ url_for('index') }}">アプリケーション開発入門</a>
           </div>
           <div class="navbar-collapse collapse">
               <ul class="nav navbar-nav">
                   <li><a href="{{ url_for('index') }}">HOME</a></li>
               </ul>
           </div>
       </div>
   </div>
{% endblock %}

{% block content %}
   <div class="container">
       {% block page_content %}{% endblock %}
   </div>
{% endblock %}

Bootstrapのスタイルは説明しませんが、ナビゲーションを作っています。

各画面を作る場合は、{% block page_content %}{% endblock %}を再定義すれば良いです。

{% import "bootstrap/wtf.html" as wtf %}は、マクロをimportしています。
テンプレートファイルで、wtf-formにBootstrapのスタイル適応するのに使います。

url_forのリンク生成

リンクをするhrefで使用しているurl_forはflaskのメソッドです。
view関数名を指定すると、APIエンドポイントを返してくれます。

@app.route('/user/<user_id>' )のように動的なエンドポイントの場合は、
url_for('user', user_id=123)のように引数を渡すと、/user/123を返してくれます

今回学んだこと

・テンプレートファイルの継承により、ベースレイアウトを作成しました
・flask-bootstrapの利用方法
・url_forでエンドポイントへのリンクパスを生成できます

参考

Flask Web Development: Developing Web Applications with Python

補足

bootstrap/base.html(Flask-Bootstrap==3.3.7.1)では、以下のようにブロックが定義されています。
同じブロックを定義するにはsuper()を記載しないと、baseを上書きしてしまいます。

<!DOCTYPE html>
<html{% block html_attribs %}{% endblock html_attribs %}>
{%- block html %}
 <head>
   {%- block head %}
   <title>{% block title %}{{title|default}}{% endblock title %}</title>
   {%- block metas %}
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   {%- endblock metas %}
   {%- block styles %}
   <!-- Bootstrap -->
   <link href="{{bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')}}" rel="stylesheet">
   {%- endblock styles %}
   {%- endblock head %}
 </head>
 <body{% block body_attribs %}{% endblock body_attribs %}>
   {% block body -%}
   {% block navbar %}
   {%- endblock navbar %}
   {% block content -%}
   {%- endblock content %}
   {% block scripts %}
   <script src="{{bootstrap_find_resource('jquery.js', cdn='jquery')}}"></script>
   <script src="{{bootstrap_find_resource('js/bootstrap.js', cdn='bootstrap')}}"></script>
   {%- endblock scripts %}
   {%- endblock body %}
 </body>
{%- endblock html %}
</html>
{% endblock doc -%}



この記事が気に入ったらサポートをしてみませんか?