見出し画像

【第6回】FlaskでWebアプリ作成練習。ページレイアウトを継承する。

こんにちは(@t_kun_kamakiri)

前回↓に引き続き、「Flask」の勉強を進めていきたいと思います。

今回は、「layout.html」ファイルをテンプレートファイルにしてhtmlファイルをFlaskでブラウザ上に表示させる方法を紹介します。

では、やっていきましょう(^^)/

☟こちらの参考書で勉強しています。

ファイル構成

ファイル構成は前回同様、このようにしておきます。

-run.py
-templates
  |- index.html
  |- layout.html
-static
  |- style.css

何をやるのか?Jinjaの「テンプレートの継承」機能を使う。

今回何をやるのかを簡単に説明しておきます。

今までは、「run.py」ファイルに以下に書くことで「index.html」を読み込む方法をとっていました。

@app.route('/',methods=['GET'])
def index():
   return render_template('index.html')

でも、今後複雑な(ページ数の多い)Webアプリを作っていく場合においては、各ページのレイアウトに統一性を持たせる必要があります。

そうすると、「index.html」ファイルのようなレイアウトを何個も作る必要があって手間がかかります。

ひとつのファイルを修正しては、別のファイルも同じように修正して・・・・などしていては効率が悪いです。

そこで、「layout.html」というテンプレートファイルを作っておいて「index.html」は「layout.html」を参照して必要な部分だけ変更するようにしてやればよいです。

全体のイメージ図が以下です。

画像1

このようにJinjaには「テンプレートの継承」機能があります。

テンプレートファイル「layout.html」を作成する


では、ブラウザで表示する「layout.html」ファイルを書いていきます。

./templates/layout.html

<!doctype html>
<html lang="en">
 <head>
   <!--  CSS -->
    <link rel="stylesheet" href="../static/style.css"> 
   <!--<link rel="stylesheet" href="{{url_for('static',filename = 'style.css')}}">-->

   <title>{% block title %}{% endblock %} </title>
 </head>

 <body>
   <header>
     <h1><strong>{% block headline %}{% endblock %}</strong></h1>        
     {% block content %}{% endblock %}
   </header>

 
 <div class="footer">
   {% block footer %}{% endblock %}
 </div>

 </body>
</html>

ここでは、「ブロック」という記述を使ってひとかたまりのコンテンツをhtmlファイルに書き込んでいます。

タイトルを指定
{% block title %}{% endblock %}
Webページの冒頭のタイトル
{% block headline %}{% endblock %}
Webページ内のコンテンツ
{% block content %}{% endblock %}
フッター部分
{% block footer %}{% endblock %}

4つのブロックを「layout.html」に埋め込んでいます。

これを変数のように使います。
そのために「index.html」ファイルにブロックに何を書き込むのかを指定してやります。

「index.html」に「layout.html」を継承する」

layout.htmlファイルをテンプレートにしているので、index.htmlファイルはブロックに何を記述するかを書くだけのシンプルなものになります。

./templates/index.html

{% extends "layout.html" %}

{% block title %}
{{title}}
{% endblock %}

{% block headline %}
{{h2_title}}
{% endblock %}

{% block content %}
<p>{{message}}</p>
<p>{{'aの値は?:%s' | format(a)}}</p>
<p>{{'data_listのリストは?:%s' | format(data_list)}}</p>
<p>{{data_list | sum}}</p>
<p>{{'data_listの確認:%s' | format(data_list)}}</p>
{% endblock %}

{% block footer %}
&copy; kamakiri
{% endblock %}

めっちゃシンプルです!

大事なのは1行目で、

{% extends "layout.html" %}

として「layout.html」を継承しています。

画像2

run.py

from flask import Flask, render_template, url_for
import random

app = Flask(__name__)

@app.route('/',methods=['GET'])
def index():
   #aに1~10のランダムな数字をいれる
   a = random.randrange(1,100)
   data_list = [ i for i in range(a)]
   return render_template('index.html', \
       title = 'Flask入門',\
       h2_title = '計算してみよう',\
       message = 'Flask入門へようこそ!',\
       a =a,\
       data_list = data_list)
       
@app.template_filter('sum')
def sum_filter(data_list):
   num = 0
   for i in data_list:
       num += i
   return num

app.jinja_env.filters['sum'] = sum_filter

if __name__ == '__main__':
   app.run()
@app.route('/',methods=['GET'])

で「'/'」にアクセスがあったらすぐ下の「index関数」が実行されるというわけです。

引数として以下のものを、「index.html」に引き渡しています。

●title = 'Flask入門'
●h2_title = '計算してみよう'
●message = 'Flask入門へようこそ!'
●a =a
●data_list = data_list

少し関係性がわかりづらいので、以下を見てください。

画像6

関係性がわかるかと思います。

Jinjaで独自の処理を行うフィルター機能を作ろう

「index.html」の中の、

<p>{{data_list | sum}}</p>

は、sumという独自で作ったJinjaのフィルター機能を使っています。

では、どうやって独自のフィルター機能を作るかというと、run.pyに以下のように書いておきます。

@app.template_filter('sum')
def sum_filter(data_list):
   num = 0
   for i in data_list:
       num += i
   return num

app.jinja_env.filters['sum'] = sum_filter

「sum」というフィルター名に対応した処理を行いますよ、という意味で

@app.template_filter('sum')

を用意します。

その下に処理をする関数を用意します。

def sum_filter(data_list):
  num = 0
  for i in data_list:
    num += i
  return num

sum_filter関数には引数としてrun.pyで定義したdata_listを入れています。

そして関数内で処理した内容を「return num」で値を返しています。

最後に作成した関数を登録します。
関数の登録は以下のように記述します。

app.jinja_env.filters[名前] = 関数名

画像7


run.pyを実行してブラウザ上に表示してみよう

では、ブラウザ上でどのように表示されるか確認しましょう。

コマンドプロンプトを立ち上げて「run.py」を実行します。

画像5

そしてhttp://127.0.0.1:5000/にアクセスします。

そうすると↓こんな感じで表示されると思います。

キャプチャ

今回は行ったことは少々わかりずらいので「index.html」で書いた内容と比較して(↓)理解しておきましょう(^^)/

画像4

では、今回は以上です。

Twitter➡@t_kun_kamakiri
ブログ➡宇宙に入ったカマキリ(物理ブログ)


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