Flaskアプリケーションでテンプレートを使用する方法

提供:Dev Guides
移動先:案内検索

著者は、 Write for DOnations プログラムの一環として、 Free and Open SourceFundを選択して寄付を受け取りました。

序章

Flask は、Python言語でWebアプリケーションを作成するための便利なツールと機能を提供する軽量のPythonWebフレームワークです。

Webアプリケーションを開発するときは、ビジネスロジックプレゼンテーションロジックから分離することが重要です。 ビジネスロジックは、ユーザーリクエストを処理し、データベースと通信して適切な応答を構築するものです。 プレゼンテーションロジックは、データをユーザーに提示する方法です。通常、HTMLファイルを使用して応答Webページの基本構造を構築し、CSSスタイルを使用してHTMLコンポーネントのスタイルを設定します。 たとえば、ソーシャルメディアアプリケーションでは、ユーザーがログインしていない場合にのみ表示できるユーザー名フィールドとパスワードフィールドがある場合があります。 ユーザーがログインしている場合は、代わりにログアウトボタンを表示します。 これがプレゼンテーションロジックです。 ユーザーがユーザー名とパスワードを入力すると、Flaskを使用してビジネスロジックを実行できます。リクエストからデータ(ユーザー名とパスワード)を抽出し、資格情報が正しい場合はユーザーにログインするか、エラーメッセージで応答します。 エラーメッセージの表示方法は、プレゼンテーションロジックによって処理されます。

Flaskでは、Jinjaテンプレート言語を使用してHTMLテンプレートをレンダリングできます。 template は、固定コンテンツと動的コンテンツの両方を含むことができるファイルです。 ユーザーがアプリケーション(インデックスページやログインページなど)に何かを要求すると、Jinjaでは、変数など、標準のHTMLでは利用できない多くの機能を使用できるHTMLテンプレートで応答できます[X237X ] ステートメント、forループ、フィルター、およびテンプレートの継承。 これらの機能により、保守が容易なHTMLページを効率的に作成できます。 Jinjaは、クロスサイトスクリプティング(XSS)攻撃を防ぐために、HTMLを自動的にエスケープします。

このチュートリアルでは、いくつかのHTMLファイルをレンダリングする小さなWebアプリケーションを作成します。 変数を使用して、サーバーからテンプレートにデータを渡します。 テンプレートの継承は、繰り返しを避けるのに役立ちます。 条件やループなどのテンプレートでロジックを使用し、フィルターを使用してテキストを変更し、Bootstrapツールキットを使用してアプリケーションのスタイルを設定します。

前提条件

ステップ1—テンプレートのレンダリングと変数の使用

環境をアクティブ化し、Flaskがインストールされていることを確認してください。そうすれば、アプリケーションの構築を開始できます。 最初のステップは、インデックスページに訪問者を迎えるメッセージを表示することです。 Flaskのrender_template()ヘルパー関数を使用して、応答としてHTMLテンプレートを提供します。 また、アプリケーション側からテンプレートに変数を渡す方法についても説明します。

まず、flask_appディレクトリで、app.pyという名前のファイルを開いて編集します。 nanoまたはお気に入りのテキストエディタを使用します。

nano app.py

app.pyファイル内に次のコードを追加します。

フラスコ_app/app.py

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def hello():
    return render_template('index.html')

ファイルを保存して閉じます。

このコードブロックでは、Flaskクラスとrender_template()関数をflaskパッケージからインポートします。 Flaskクラスを使用して、appという名前のFlaskアプリケーションインスタンスを作成します。 次に、app.route()デコレータを使用して、hello()というビュー関数(HTTP応答を返すPython関数)を定義します。これにより、通常の関数がビュー関数に変換されます。 。 このビュー関数は、render_template()関数を使用して、index.htmlというテンプレートファイルをレンダリングします。

次に、flask_appディレクトリ内のtemplatesというディレクトリにindex.htmlテンプレートファイルを作成する必要があります。 Flaskはtemplatesディレクトリでテンプレートを探します。これはtemplatesと呼ばれるため、名前は重要です。 flask_appディレクトリ内にいることを確認し、次のコマンドを実行してtemplatesディレクトリを作成します。

mkdir templates

次に、templatesディレクトリ内のindex.htmlというファイルを開いて編集します。 ここでの名前index.htmlは、標準の必須の名前ではありません。 必要に応じて、home.htmlまたはhomepage.htmlまたはその他の名前を付けることができます。

nano templates/index.html

index.htmlファイル内に次のHTMLコードを追加します。

フラスコ_app/templates / index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>FlaskApp</title>
</head>
<body>
    <h1>Hello World!</h1>
    <h2>Welcome to FlaskApp!</h2>
</body>
</html>

ここでは、タイトルを設定し、Hello World!メッセージをH1見出しとして追加し、Welcome to FlaskApp!メッセージをH2見出しとして作成しました。

ファイルを保存して閉じます。

仮想環境をアクティブにしてflask_appディレクトリにいるときに、FLASK_APP環境変数を使用してアプリケーション(この場合はapp.py)についてFlaskに通知し、[を設定します。 X191X]環境変数をdevelopmentに設定して、アプリケーションを開発モードで実行し、デバッガーにアクセスします。 これを行うには、次のコマンドを使用します(Windowsでは、exportの代わりにsetを使用します)。

export FLASK_APP=app
export FLASK_ENV=development

次に、flask runコマンドを使用してアプリケーションを実行します。

flask run

開発サーバーが実行されている状態で、ブラウザーを使用して次のURLにアクセスします。

http://127.0.0.1:5000/

ページのタイトルがFlaskAppに設定され、2つの見出しがHTMLでレンダリングされていることがわかります。

Webアプリケーションでは、多くの場合、アプリケーションのPythonファイルからHTMLテンプレートにデータを渡す必要があります。 このアプリケーションでこれを行う方法を示すために、現在のUTC日時を含む変数をインデックステンプレートに渡し、変数の値をテンプレートに表示します。

サーバーを実行したままにし、app.pyファイルを開いて新しい端末で編集します。

nano app.py

Python標準ライブラリからdatetimeモジュールをインポートし、index()関数を編集してファイルが次のようになるようにします。

フラスコ_app/app.py

import datetime
from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def hello():
    return render_template('index.html', utc_dt=datetime.datetime.utcnow())

ファイルを保存して閉じます。

ここでは、datetimeモジュールをインポートし、utc_dtという変数をindex.htmlテンプレートにdatetime.datetime.utcnow()の値で渡しました。これは現在のUTC日時です。 。

次に、変数の値をインデックスページに表示するには、index.htmlファイルを開いて編集します。

nano templates/index.html

次のようにファイルを編集します。

フラスコ_app/templates / index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>FlaskApp</title>
</head>
<body>
    <h1>Hello World!</h1>
    <h2>Welcome to FlaskApp!</h2>
    <h3>{{ utc_dt }}</h3>
</body>
</html>

ファイルを保存して閉じます。

utc_dt変数の値を出力するために、特別なテンプレート:...区切り文字を使用してH3見出しを追加しました。

ブラウザを開き、インデックスページにアクセスします。

http://127.0.0.1:5000/

次の画像のようなページが表示されます。

これで、FlaskアプリケーションでHTMLテンプレートを使用してインデックスページを作成し、テンプレートをレンダリングして、変数値を渡して表示しました。 次に、テンプレートの継承を使用してコードの繰り返しを回避します。

ステップ2—テンプレートの継承を使用する

このステップでは、他のテンプレートと共有できるコンテンツを含むベーステンプレートを作成します。 ベーステンプレートから継承するようにインデックステンプレートを編集します。 次に、アプリケーションの[バージョン情報]ページとして機能する新しいページを作成します。このページで、ユーザーはアプリケーションに関する詳細情報を見つけることができます。

ベーステンプレートには、アプリケーションのタイトル、ナビゲーションバー、フッターなど、他のすべてのテンプレート間で通常共有されるHTMLコンポーネントが含まれています。

まず、テンプレートディレクトリ内で編集するためにbase.htmlという新しいファイルを開きます。

nano templates/base.html

base.htmlファイル内に次のコードを記述します。

フラスコ_app/templates / base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %} - FlaskApp</title>
    <style>
        nav a {
            color: #d64161;
            font-size: 3em;
            margin-left: 50px;
            text-decoration: none;
        }
    </style>
</head>
<body>
    <nav>
        <a href="#">FlaskApp</a>
        <a href="#">About</a>
    </nav>
    <hr>
    <div class="content">
        {% block content %} {% endblock %}
    </div>
</body>
</html>

ファイルを保存して閉じます。

このファイルのコードのほとんどは、標準のHTML、タイトル、ナビゲーションリンクのスタイル、2つのリンクがあるナビゲーションバーです。1つはインデックスページ用で、もう1つはまだ作成されていないAboutページ用です。 [X206X ]ページのコンテンツ用。 (リンクはまだ機能しません。次のステップでは、ページ間をリンクする方法を示します)。

ただし、以下の強調表示されている部分は、Jinjaテンプレートエンジンに固有のものです。

  • {% block title %} {% endblock %}:タイトルのプレースホルダーとして機能するブロック。 後で他のテンプレートで使用して、<head>セクション全体を毎回書き直すことなく、アプリケーションの各ページにカスタムタイトルを提供します。
  • {% block content %} {% endblock %}子テンプレートbase.htmlから継承するテンプレート)に応じてコンテンツに置き換えられる別のブロックで、それをオーバーライドします。

基本テンプレートができたので、継承を使用してそれを利用できます。 index.htmlファイルを開きます。

nano templates/index.html

次に、その内容を次のように置き換えます。

フラスコ_app/templates / index.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Index {% endblock %}</h1>
    <h1>Hello World!</h1>
    <h2>Welcome to FlaskApp!</h2>
    <h3>{{ utc_dt }}</h3>
{% endblock %}

ここでは、{% extends %}タグを使用して、base.htmlテンプレートから継承します。 次に、ベーステンプレートのcontentブロックを、前のコードブロックのcontentブロック内にあるものに置き換えることで拡張します。

このコンテンツブロックには、タイトルブロック内にテキストIndexを含む<h1>タグが含まれています。これにより、base.htmlテンプレートの元のtitleブロックがIndexとテキストを入力して、完全なタイトルがIndex - FlaskAppになるようにします。 このように、同じテキストが2回繰り返されるのを避けることができます。これは、ページのタイトルと、ベーステンプレートから継承されたナビゲーションバーの下に表示される見出しの両方として機能するためです。

次に、さらにいくつかの見出しがあります。1つの<h1>見出しには、テキストHello World!<h2>見出し、および<h3>見出しには[ X157X]変数。

テンプレートの継承により、必要になるたびに繰り返すことなく、他のテンプレート(この場合はbase.html)にあるHTMLコードを再利用できます。

ファイルを保存して閉じ、ブラウザのインデックスページを更新します。 ページは次のようになります。

次に、Aboutページを作成します。 app.pyファイルを開いて、新しいルートを追加します。

nano app.py

ファイルの最後に次のルートを追加します。

フラスコ_app/app.py

# ...
@app.route('/about/')
def about():
    return render_template('about.html')

ここでは、app.route()デコレータを使用して、about()というビュー関数を作成します。 その中で、about.htmlテンプレートファイル名を引数としてrender_template()関数を呼び出した結果を返します。

ファイルを保存して閉じます。

編集用にabout.htmlというテンプレートファイルを開きます。

nano templates/about.html

次のコードをファイルに追加します。

フラスコ_app/templates / about.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} About {% endblock %}</h1>
    <h3>FlaskApp is a Flask web application written in Python.</h3>
{% endblock %}

ここでは、extendsタグを使用してベーステンプレートから継承し、ベーステンプレートのcontentブロックを、ページのタイトルを兼ねる<h1>タグに置き換え、[ X181X]タグとアプリケーションに関する情報。

ファイルを保存して閉じます。

開発サーバーが実行されている状態で、ブラウザーを使用して次のURLにアクセスします。

http://127.0.0.1:5000/about

次のようなページが表示されます。

ナビゲーションバーとタイトルの一部がベーステンプレートからどのように継承されているかに注目してください。

これでベーステンプレートが作成され、コードの繰り返しを避けるためにインデックスページとアバウトページで使用されました。 ナビゲーションバーのリンクは、この時点では何もしません。 次のステップでは、ナビゲーションバーのリンクを修正して、テンプレート内のルート間をリンクする方法を学習します。

ステップ3—ページ間のリンク

このステップでは、 url_for()ヘルパー関数を使用してテンプレート内のページ間をリンクする方法を学習します。 ベーステンプレートのナビゲーションバーに2つのリンクを追加します。1つはインデックスページ用で、もう1つは[バージョン情報]ページ用です。

まず、編集用にベーステンプレートを開きます。

nano templates/base.html

次のようにファイルを編集します。

フラスコ_app/templates / base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %} - FlaskApp</title>
    <style>
        nav a {
            color: #d64161;
            font-size: 3em;
            margin-left: 50px;
            text-decoration: none;
        }
    </style>
</head>
<body>
    <nav>
        <a href="{{ url_for('hello') }}">FlaskApp</a>
        <a href="{{ url_for('about') }}">About</a>
    </nav>
    <hr>
    <div class="content">
        {% block content %} {% endblock %}
    </div>
</body>
</html>

ここでは、指定したビュー関数のURLを返す特別な url_for()関数を使用します。 最初のリンクは、hello()ビュー機能(インデックスページ)のルートにリンクしています。 2番目のリンクは、about()ビュー機能のルートにリンクしています。 ルート(/または/about)ではなく、ビュー関数の名前を渡すことに注意してください。

url_for()関数を使用してURLを作成すると、URLをより適切に管理できます。 URLをハードコーディングした場合、ルートを編集するとリンクが壊れます。 url_for()を使用すると、ルートを編集して、リンクが引き続き期待どおりに機能することを保証できます。 url_for()関数は、特殊文字のエスケープなどの他の処理も行います。

ファイルを保存して閉じます。

次に、インデックスページに移動して、ナビゲーションバーのリンクを試してください。 期待どおりに機能することがわかります。

url_for()関数を使用して、テンプレート内の他のルートにリンクする方法を学習しました。 次に、設定した条件に応じてテンプレートに表示される内容を制御する条件ステートメントをいくつか追加し、テンプレートでforループを使用してリストアイテムを表示します。

ステップ4—条件とループの使用

このステップでは、テンプレートでifステートメントを使用して、特定の条件に応じて表示する内容を制御します。 また、forループを使用して、Pythonリストを調べ、リスト内の各項目を表示します。 リストにコメントを表示する新しいページを追加します。 インデックス番号が偶数のコメントは背景が青色になり、インデックス番号が奇数のコメントは背景が灰色で表示されます。

まず、コメントページのルートを作成します。 app.pyファイルを開いて編集します。

nano app.py

ファイルの最後に次のルートを追加します。

フラスコ_app/app.py

# ...

@app.route('/comments/')
def comments():
    comments = ['This is the first comment.',
                'This is the second comment.',
                'This is the third comment.',
                'This is the fourth comment.'
                ]

    return render_template('comments.html', comments=comments)

上記のルートには、4つのアイテムを含むcommentsというPythonリストがあります。 (これらのコメントは通常、ここで行ったようにハードコーディングされるのではなく、実際のシナリオのデータベースから取得されます。)最後の行にcomments.htmlというテンプレートファイルを返し、次の変数を渡します。テンプレートファイルへのリストを含むcomments

ファイルを保存して閉じます。

次に、templatesディレクトリ内の新しいcomments.htmlファイルを開いて編集します。

nano templates/comments.html

次のコードをファイルに追加します。

フラスコ_app/templates/comments.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
        <div style="padding: 10px; background-color: #EEE; margin: 20px">
            <p style="font-size: 24px">{{ comment }}</p>
        </div>
        {% endfor %}
    </div>
{% endblock %}

ここでは、base.htmlテンプレートを拡張し、contentブロックの内容を置き換えます。 まず、ページのタイトルとしても機能する<h1>見出しを使用します。

{% for comment in comments %}行のJinjaforループを使用して、commentsリスト(comment変数に格納されます)の各コメントを調べます。 コメントは、通常Jinjaで変数を表示するのと同じ方法で、<p style="font-size: 24px">テンプレート:Comment</p>タグに表示します。 {% endfor %}キーワードを使用して、forループの終了を通知します。 これは、Jinjaテンプレートに特別なインデントがないため、Pythonforループの構築方法とは異なります。

ファイルを保存して閉じます。

開発サーバーが実行されている状態で、ブラウザーを開き、コメントページにアクセスします。

http://127.0.0.1:5000/comments

次のようなページが表示されます。

次に、テンプレートでif条件ステートメントを使用して、背景が灰色の奇数のインデックス番号のコメントと、背景が青色の偶数のインデックス番号のコメントを表示します。

comments.htmlテンプレートファイルを開いて編集します。

nano templates/comments.html

次のように編集します。

フラスコ_app/templates/comments.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            {% if loop.index % 2 == 0 %}
                {% set bg_color = '#e6f9ff' %}
            {% else %}
                {% set bg_color = '#eee' %}
            {% endif %}

            <div style="padding: 10px; background-color: {{ bg_color }}; margin: 20px">
                <p>#{{ loop.index }}</p>
                <p style="font-size: 24px">{{ comment }}</p>
            </div>
        {% endfor %}
    </div>
{% endblock %}

この新しい編集では、{% if loop.index % 2 == 0 %}行にifステートメントを追加しました。 ループ変数は、現在のループに関する情報にアクセスできる特別なJinja変数です。 ここでは、loop.indexを使用して、Pythonリストのように0ではなく、1から始まる現在のアイテムのインデックスを取得します。

ここでのifステートメントは、インデックスが%演算子を使用しているかどうかをチェックします。 インデックス番号を2で割った余りをチェックします。 余りが0の場合、インデックス番号が偶数であることを意味します。それ以外の場合、インデックス番号は奇数です。 {% set %}タグを使用して、bg_colorという変数を宣言します。 インデックス番号が偶数の場合は青みがかった色に設定し、インデックス番号が奇数の場合はbg_color変数を灰色に設定します。 次に、bg_color変数を使用して、コメントを含む<div>タグの背景色を設定します。 コメントのテキストの上で、loop.indexを使用して、現在のインデックス番号を<p>タグで表示します。

ファイルを保存して閉じます。

ブラウザを開き、コメントページにアクセスします。

http://127.0.0.1:5000/comments

新しいコメントページが表示されます。

これは、ifステートメントの使用方法のデモンストレーションでした。 ただし、特別なloop.cycle()Jinjaヘルパーを使用して同じ効果を達成することもできます。 これを示すために、comments.htmlファイルを開きます。

nano templates/comments.html

次のように編集します。

フラスコ_app/templates/comments.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            <div style="padding: 10px;
                        background-color: {{ loop.cycle('#EEE', '#e6f9ff') }};
                        margin: 20px">
                <p>#{{ loop.index }}</p>
                <p style="font-size: 24px">{{ comment }}</p>
            </div>
        {% endfor %}
    </div>
{% endblock %}

ここでは、if/elseステートメントを削除し、loop.cycle('#EEE', '#e6f9ff')ヘルパーを使用して2つの色を切り替えました。 background-colorの値は、あるときは#EEEになり、別のときは#e6f9ffになります。

ファイルを保存して閉じます。

ブラウザでコメントページを開いて更新すると、ifステートメントと同じ効果があることがわかります。

ifステートメントは、ページに表示される内容の制御など、さまざまな目的に使用できます。 たとえば、2番目のコメントを除くすべてのコメントを表示するには、条件loop.index != 2ifステートメントを使用して、2番目のコメントを除外できます。

コメントテンプレートを開きます。

nano templates/comments.html

そして、次のように編集します。

フラスコ_app/templates/comments.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            {% if loop.index != 2 %}
                <div style="padding: 10px;
                            background-color: #EEE;
                            margin: 20px">
                    <p>#{{ loop.index }}</p>
                    <p style="font-size: 24px">{{ comment }}</p>
                </div>
            {% endif %}
        {% endfor %}
    </div>
{% endblock %}

ここでは、{% if loop.index != 2 %}を使用して、インデックス2を持たないコメントのみを表示します。これは、2番目のコメントを除くすべてのコメントを意味します。 また、loop.cycle()ヘルパーの代わりにハードコードされた背景色の値を使用して、作業を簡単にします。残りは変更されません。 {% endif %}を使用して、ifステートメントを終了します。

ファイルを保存して閉じます。

コメントページを更新すると、2番目のコメントが表示されていないことがわかります。

次に、ナビゲーションバーのコメントページにユーザーを誘導するリンクを追加する必要があります。 編集用にベーステンプレートを開きます。

nano templates/base.html

新しい<a>リンクを追加して、<nav>タグの内容を編集します。

フラスコ_app/templates / base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %} - FlaskApp</title>
    <style>
        nav a {
            color: #d64161;
            font-size: 3em;
            margin-left: 50px;
            text-decoration: none;
        }
    </style>
</head>
<body>
    <nav>
        <a href="{{ url_for('hello') }}">FlaskApp</a>
        <a href="{{ url_for('comments') }}">Comments</a>
        <a href="{{ url_for('about') }}">About</a>
    </nav>
    <hr>
    <div class="content">
        {% block content %} {% endblock %}
    </div>
</body>
</html>

ここでは、url_for()ヘルパーを使用して、comments()ビュー機能にリンクします。

ファイルを保存して閉じます。

ナビゲーションバーに、コメントページにリンクする新しいリンクが追加されます。

テンプレートでifステートメントを使用して、特定の条件に応じて表示する内容を制御しました。 forループを使用してPythonリストを調べ、リスト内の各項目を表示し、Jinjaの特別なloop変数について学習しました。 次に、Jinjaフィルターを使用して、変数データの表示方法を制御します。

ステップ5—フィルターの使用

このステップでは、テンプレートでJinjaフィルターを使用する方法を学習します。 upperフィルターを使用して、前の手順で追加したコメントを大文字に変換し、joinフィルターを使用して、一連の文字列を1つの文字列に結合します。 safeフィルターを使用して、信頼できるHTMLコードをエスケープせずにレンダリングする方法を学びます。

まず、コメントページのコメントを大文字に変換します。 comments.htmlテンプレートを開いて編集します。

nano templates/comments.html

次のように編集します。

フラスコ_app/templates/comments.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            {% if loop.index != 2 %}
                <div style="padding: 10px;
                            background-color: #EEE;
                            margin: 20px">
                    <p>#{{ loop.index }}</p>
                    <p style="font-size: 24px">{{ comment | upper }}</p>
                </div>
            {% endif %}
        {% endfor %}
    </div>
{% endblock %}

ここでは、パイプ記号(|)を使用してupper filterを追加しました。 これにより、comment変数の値が大文字に変更されます。

ファイルを保存して閉じます。

開発サーバーが実行されている状態で、ブラウザーでコメントページを開きます。

http://127.0.0.1:5000/comments

フィルタを適用すると、コメントがすべて大文字になっていることがわかります。

フィルタは、括弧内に引数を取ることもできます。 これを示すために、joinフィルターを使用して、commentsリストのすべてのコメントを結合します。

コメントテンプレートを開きます。

nano templates/comments.html

次のように編集します。

フラスコ_app/templates/comments.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            {% if loop.index != 2 %}
                <div style="padding: 10px;
                            background-color: #EEE;
                            margin: 20px">
                    <p>#{{ loop.index }}</p>
                    <p style="font-size: 24px">{{ comment | upper }}</p>
                </div>
            {% endif %}
        {% endfor %}
        <hr>
        <div>
            <p>{{ comments | join(" | ") }}</p>
        </div>
    </div>
{% endblock %}

ここでは、<hr>タグと<div>タグを追加し、join()フィルターを使用してcommentsリストのすべてのコメントを結合します。

ファイルを保存して閉じます。

コメントページを更新すると、次のようなページが表示されます。

ご覧のとおり、commentsリストは、join()フィルターに渡したものであるパイプ記号で区切られたコメントとともに表示されます。

もう1つの重要なフィルターは、safeフィルターです。これにより、ブラウザーで信頼できるHTMLをレンダリングできます。 これを説明するために、{{ }} Jinja区切り文字を使用して、HTMLタグを含むテキストをコメントテンプレートに追加します。 実際のシナリオでは、これはサーバーからの変数として提供されます。 次に、join()引数を編集して、パイプ記号ではなく<hr>タグにします。

コメントテンプレートを開きます。

nano templates/comments.html

次のように編集します。

フラスコ_app/templates/comments.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            {% if loop.index != 2 %}
                <div style="padding: 10px;
                            background-color: #EEE;
                            margin: 20px">
                    <p>#{{ loop.index }}</p>
                    <p style="font-size: 24px">{{ comment | upper }}</p>
                </div>
            {% endif %}
        {% endfor %}
        <hr>
        <div>
            {{ "<h1>COMMENTS</h1>" }}
            <p>{{ comments | join(" <hr> ") }}</p>
        </div>
    </div>
{% endblock %}

ここでは、値"<h1>COMMENTS</h1>"を追加し、結合引数を<hr>タグに変更しました。

ファイルを保存して閉じます。

コメントページを更新すると、次のようなページが表示されます。

ご覧のとおり、HTMLタグはレンダリングされていません。 一部のHTMLタグは有害であり、クロスサイトスクリプティング(XSS)攻撃を引き起こす可能性があるため、これはJinjaの安全機能です。 信頼できるHTMLのみをブラウザでレンダリングできるようにする必要があります。

上記のHTMLタグをレンダリングするには、コメントテンプレートファイルを開きます。

nano templates/comments.html

safeフィルターを追加して編集します。

フラスコ_app/templates/comments.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            {% if loop.index != 2 %}
                <div style="padding: 10px;
                            background-color: #EEE;
                            margin: 20px">
                    <p>#{{ loop.index }}</p>
                    <p style="font-size: 24px">{{ comment | upper }}</p>
                </div>
            {% endif %}
        {% endfor %}
        <hr>
        <div>
            {{ "<h1>COMMENTS</h1>" | safe }}
            <p>{{ comments | join(" <hr> ") | safe }}</p>
        </div>
    </div>
{% endblock %}

<p>テンプレート:Comments</p>のようにフィルターをチェーンすることもできることがわかります。 各フィルターは、前のフィルターの結果に適用されます。

ファイルを保存して閉じます。

コメントページを更新すると、HTMLタグが期待どおりにレンダリングされていることがわかります。

警告:不明なデータソースからのHTMLでsafeフィルターを使用すると、アプリケーションがXSS攻撃にさらされる可能性があります。 レンダリングするHTMLが信頼できるソースからのものでない限り、使用しないでください。


詳細については、組み込みのJinjaフィルターのリストを確認してください。

これで、Jinjaテンプレートでフィルターを使用して変数値を変更する方法を学習しました。 次に、Bootstrapツールキットを統合してアプリケーションのスタイルを設定します。

ステップ6—ブートストラップの統合

このステップでは、Bootstrapツールキットを使用してアプリケーションのスタイルを設定する方法を学習します。 ベーステンプレートから継承するすべてのページに表示されるブートストラップナビゲーションバーをベーステンプレートに追加します。

Bootstrapツールキットは、アプリケーションのスタイルを設定して、視覚的に魅力的なものにするのに役立ちます。 また、レスポンシブWebページをWebアプリケーションに組み込んで、これらの目標を達成するために独自のHTML、CSS、およびJavaScriptコードを記述しなくてもモバイルブラウザーで適切に機能するようにするのにも役立ちます。

Bootstrapを使用するには、Bootstrapをベーステンプレートに追加して、他のすべてのテンプレートで使用できるようにする必要があります。

base.htmlテンプレートを開いて、編集します。

nano templates/base.html

次のように編集します。

フラスコ_app/templates / base.html

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">

    <title>{% block title %} {% endblock %} - FlaskApp</title>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
    <div class="container-fluid">
        <a class="navbar-brand" href="{{ url_for('hello') }}">FlaskApp</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
            <li class="nav-item">
              <a class="nav-link" href="{{ url_for('comments') }}">Comments</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="{{ url_for('about') }}">About</a>
            </li>
        </ul>
        </div>
    </div>
    </nav>
    <div class="container">
        {% block content %} {% endblock %}
    </div>

    <!-- Optional JavaScript -->

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>

  </body>
</html>

上記のコードのほとんどは、それを使用するために必要なブートストラップボイラープレートです。 いくつかのメタタグ、<head>セクションのブートストラップCSSファイルへのリンクがあり、下部にオプションのJavaScriptへのリンクがあります。 コードの強調表示された部分には、前の手順で説明したJinjaコードが含まれています。 特定のタグとCSSクラスを使用して、各要素の表示方法をBootstrapに指示する方法に注目してください。

上記の<nav>タグには、クラスnavbar-brand<a>タグがあり、ナビゲーションバーのブランドリンクを決定します。 <ul class="navbar-nav">タグ内には、<li>タグ内の<a>タグ内に通常のナビゲーションバーアイテムがあります。

これらのタグとCSSクラスの詳細については、ブートストラップコンポーネントを参照してください。

ファイルを保存して閉じます。

開発サーバーが実行されている状態で、ブラウザーでインデックスページを開きます。

http://127.0.0.1:5000/

次のようなページが表示されます。

Bootstrapコンポーネントを使用して、すべてのテンプレートのFlaskアプリケーションでアイテムのスタイルを設定できるようになりました。

結論

これで、FlaskWebアプリケーションでHTMLテンプレートを使用する方法がわかりました。 サーバーからテンプレートにデータを渡すために変数を使用し、繰り返しを避けるためにテンプレートの継承を採用し、if条件やforループなどの要素を組み込み、異なるページ間でリンクしました。 テキストを変更して信頼できるHTMLを表示するためのフィルターについて学び、Bootstrapをアプリケーションに統合しました。

Flaskの詳細については、Flaskトピックページをご覧ください。