これまでは記述した文字列を関数の return でそのまま表示していましたが、この方法では複数行に渡る複雑な内容を記述するのは大変です。データと見た目を分離してプログラムからWebページを自動生成しやすくするテンプレートエンジンを使ってみましょう。
目次
テンプレートエンジンとは
テンプレートエンジンとはアプリケーションが保持するデータやプログラムが処理した結果とHTMLの雛形を組み合わせてWebページを生成する機能です。
Pythonコードの中にHTML文書を書いてしまうと可読性が悪いだけでなく、データと見た目が一体化してしまうため、デザインを変更する場合はプログラムファイルを修正する必要が出てくるという問題があります。
これだとプログラマとデザイナーが作業を分担しにくいです。
そこでアプリケーションのデータや関数の定義などは別のファイルに分離し、構造化された文書であるHTMLの中にはPythonの呼び出し用のコードを埋め込むことで、HTMLとしてメンテナンスできるだけでなく、プログラムのループ処理などを使うこともできるようになります。
また、データと見た目を分離できるためプログラマとデザイナーが作業を分担しやすくなります。
テンプレートで表示してみよう
実際にテンプレートエンジンを使ってWebページを表示してみましょう。
ここではJinja2というFlaskに組み込まれているPython製のテンプレートエンジンを使います。
Flaskプロジェクトのトップレベルディレクトリ(ここではflask-tutorial)に用意した hello.py に次のコードを記述します。
from flask import Flask, render_template # render_templateもインポート app = Flask(__name__) @app.route("/") def index(): return render_template("index.html") # index.htmlファイルをテンプレートとして呼び出す
ルートディレクトリのURLにアクセスがあった場合に、index.htmlファイルをテンプレートとして呼び出して返すよう記述しています。
次にテンプレート用のディレクトリを用意します。
flask-tutorial ディレクトリの下に templates という名前のフォルダを用意します。これがテンプレート用のディレクトリです。
この中に先ほどのコードで呼び出されるindex.htmlファイルを作成しましょう。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Flaskを使ってみよう!</title> </head> <body> <h1>FlaskでHello World!</h1> <p>Pythonの軽量WebアプリケーションフレームワークであるFlaskを使ってみましょう!まずはおなじみ画面上に Hello World と表示してみます。</p> </body> </html>
ブラウザで確認
flaskコマンドを使ってアプリケーションを実行し、ブラウザで確認してみましょう。
トップページ(http://127.0.0.1:5000/)にアクセスします。
先ほど作成したテンプレートページが表示できました。
プログラムからデータを渡して表示
これだけだとテンプレートをそのまま表示しているだけなので、今度はプログラムからデータを渡してそれを表示してみましょう。
テンプレートにデータを渡すには hello.py に次のように記述し render_template の引数として渡します。
from flask import Flask, render_template app = Flask(__name__) @app.route("/") def index(): name = "Flask" # ローカル変数を定義 return render_template("index.html", name_value = name) # テンプレートにローカル変数nameの中身をname_valueという変数で渡す
テンプレート側では name_value 変数でデータを取り出します。
テンプレートで変数の中身をそのまま出力するには波括弧2つ {{}} で囲みます。
index.html に次のように記述します。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Flaskを使ってみよう!</title> </head> <body> <h1>{{ name_value }}でHello World!</h1> <p>Pythonの軽量WebアプリケーションフレームワークであるFlaskを使ってみましょう!まずはおなじみ画面上に Hello World と表示してみます。</p> </body> </html>
これでhello.pyから渡した name_value 変数を取得して表示するようになりました。
flaskコマンドを使ってアプリケーションを実行し、ブラウザで確認してみましょう。
トップページ(http://127.0.0.1:5000/)にアクセスします。
ちなみにテンプレート側で呼び出した変数に値が与えられていない場合は何も表示しません。
試しに ユーザーが /about にアクセスした場合は name_value に値を与えないようにしてみましょう。
hello.py に次のように記述します。
from flask import Flask, render_template app = Flask(__name__) @app.route("/") def index(): name = "Flask" return render_template("index.html", name_value = name) # /aboutのURLをトリガーに @app.route("/about") def about(): return render_template("index.html")
トップページも /about もどちらも index.html というテンプレートファイルを呼び出しますが、/about では name 変数を定義せず、render_template の引数にもname_value変数を指定していません。
flaskコマンドを使ってアプリケーションを実行し、ブラウザで確認してみましょう。
今度は http://127.0.0.1:5000/about にアクセスします。
このように、name_value変数として記述した部分は何も表示されていません。
テンプレート側にPythonの処理を書く
Flaskではテンプレート側でもPythonのコードを書くことができます。テンプレート側でPythonのコードを書く際はその部分を {% %} で囲みます。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Flaskを使ってみよう!</title> </head> <body> {% if name_value %} <h1>{{ name_value }}でHello World!</h1> {% else %} <p>Pythonの軽量WebアプリケーションフレームワークであるFlaskを使ってみましょう!まずはおなじみ画面上に Hello World と表示してみます。</p> {% endif %} </body> </html>
インデントは付いていますがPythonのコード内にインデントがあるわけではないため、if文の終わりを示す endif が必要となります。
このコードはname_value変数に値が渡されている場合は9行目を出力し、そうでない場合は11行目のコードを出力する条件分岐文です。
flaskコマンドを使ってアプリケーションを実行し、ブラウザで確認してみましょう。
まずは http://127.0.0.1:5000/ にアクセスします。
h1タグで囲まれたFlaskでHello World!という文字列が表示されています。
次は http://127.0.0.1:5000/about にアクセスしてみましょう。
こちらはh1タグとその中身は表示されず、pタグとその中身のみが出力されています。
このように、テンプレートエンジンを使うとプログラムの関数定義などのデータとHTMLテンプレートを別のファイルとして分離したうえで、Webページとして表示する際はHTMLのテンプレートの中にPythonのプログラム処理を組み合わせて表示することができます。