コンテンツにスキップ

第2章 テンプレート

1 HTMLファイルの準備

FlaskのURLが割り当てられた関数は文字列をreturnすることで、それがブラウザに表示されます。

しかし、長いHTMLを文字列として返すのは面倒です。 そこで、HTMLファイルをあらかじめつくり、それを返すようにします。

そのHTMLファイルは、pythonファイルがあるフォルダ配下にtemplatesというフォルダを作り、そこに置くようにします。

例えば、以下の内容で、templatesフォルダ内にindex.html を置いてみます。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>トップページ</title>
</head>
<body>

<h1>トップページ</h1>

</body>
</html>

このようにtemplates内に置いたHTMLファイルをテンプレートと呼びます。

2 テンプレートの利用

templates配下に置かれたHTMLファイルを返すには render_template 関数を使って、ファイル名を指定します。

index関数で、render_template(ファイル名) をreturnするようにします。

@app.get('/')
def index():
    return render_template("index.html")

これでブラウザにアクセスすると、index.htmlファイルが表示されます。

問題

/hello にアクセスすると hello.html を表示するように修正しよう。

3 データのやりとり

現状では単純にHTMLファイルを返す静的コンテンツと変わりありません。 そこで、計算を行った結果を表示してみたいと思います。

index関数内で計算した値を変数kotaeに入れます。これをテンプレートの方にnumという名前で渡してみます。これを行うにはrender_templateの引数で渡します。

@app.get('/')
def index():
    kotae = 5 * 2
    return render_template("index.html", num=kotae)

render_template関数で 名前=値 で渡します。今回は名前はnumで、値はkotaeです。ただ、通常は分かりやすいように変数名と同じ値で渡した方が良いでしょう。

これをindex.html内で表示してみます。表示するには{{名前}}と書けばその名前で渡されたデータが表示されます。

<p>{{num}}</p>

データを複数渡すことも可能です。例えば、num1に掛け算、num2に足し算の結果を入れます。それを両方とも渡す場合、カンマで区切って渡します。

@app.get('/')
def index():
    num1 = 5 * 2
    num2 = 5 * 3
    return render_template("index.html", num1=num1, num2=num2)

問題

/hello/名前 でアクセスすると名前をnameという名で hello.html に渡し、「おはよう、○○さん」と表示するように修正しよう。

4 リストの表示

今度はリストをテンプレートに渡して表示してみます。 新たに nlist 関数を作成します。この中でdataにリストを作ります。これをdataという名前でnlist.htmlに渡します。

@app.get('/nlist')
def nlist():
    data = ["佐藤","鈴木","田中"]
    return render_template("nlist.html", data=data)

これをnlist.html内で表示してみます。リストの内容を全て表示するにはpython同様のfor文を使います。 テンプレート内にこのようなpythonと同じ命令を書くには{% ~ %} に書きます。pythonのforとの違いは、最後に : が無いこととforの終わりに endforが必要なことです。

{% for name in data %}
    <p>{{name}}</p>
{% endfor %}

この書き方は Jinja2 というテンプレートの書き方です。Jinjia2には他にもifなどの書き方があります。詳しくは公式サイトを見てください。

5 辞書の表示

続いて辞書をテンプレートに渡して表示してみます。 新たに dic 関数を作成します。この中でdataに辞書を作ります。これをdataという名前でdic.htmlに渡します。

@app.get('/dic')
def dic():
    data = {"name":"佐藤", "age":20}
    return render_template("dic.html", data=data)

これをdic.html内で表示してみます。辞書でデータを参照するには通常のpythonでは データ名["キー名"] と書きます。

<p>{{data["name"]}} 様</p>
<p>{{data["age"]}} 才</p>

しかし、テンプレート内では データ名.keyで表示できます。

<p>{{data.name}} 様</p>
<p>{{data.age}} 才</p>

なお、クラスのインスタンスを渡した場合にも同様に データ名.属性 で表示できます。

6 辞書のリストの表示

続いて辞書のリストを表示してみます。   新たに diclist 関数を作成します。この中でdataに辞書のリストを作ります。これをdataという名前でdiclist.htmlに渡します。

@app.get('/diclist')
def diclist():
    data = [{"name":"佐藤", "age":20},
            {"name":"鈴木", "age":40},
            {"name":"田中", "age":30}]
    return render_template("diclist.html", data=data)

これをdoclist.html内で表示してみます。リストの内容を全て表示するにはpython同様のfor文を使います。取り出したデータは単一の辞書なので 変数名.キー で参照できます。

{% for d in data %}
<p>{{d.name}} 様</p>
<p>{{d.age}} 才</p>
{% endfor %}

これをテーブルで表示してみましょう。

<table>
    <tr><th>名前</th><th>年齢</th></tr>
    {% for d in data %}
    <tr>
    <td>{{d.name}} 様</td>
    <td>{{d.age}} 才</td>
    </tr>
    {% endfor %}
</table>

テーブルで繰り返す部分のところをforで表示します。データ一件が一行分なので、trで囲んで、tdで一つずつ表示します。

7 静的ファイルの利用

テンプレートとして作成したHTMLは、pythonの関数を経由して表示されますが、そうではなく直接参照したいこともあります。

例えば、cssファイルや画像ファイルです。 cssファイルを利用したい場合には、templates内に置いても参照されません。 static というフォルダを作成しそこに配置します。

そして、css参照のパスは /static/ファイル名 になります。

<link rel="stylesheet" href="/static/style.css">

このように、pythonのプログラムを動かさずに参照できるファイルは静的ファイルと呼ばれます。

静的ファイルとして利用されるのは、画像やcssファイル、jsファイル(JavaScript)などです。