Flaskアプリケーションでテンプレートを使用する方法
著者は、 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ツールキットを使用してアプリケーションのスタイルを設定します。
前提条件
- ローカルのPython3プログラミング環境。 Python3シリーズのローカルプログラミング環境をインストールおよびセットアップする方法のチュートリアルに従ってください。 このチュートリアルでは、プロジェクトディレクトリを
flask_app
と呼びます。 - FlaskとPythonを使用して最初のWebアプリケーションを作成する方法のステップ1で説明されているように、プログラミング環境にインストールされたFlask。
- ルートやビュー機能などの基本的なFlaskの概念の理解。 Flaskに慣れていない場合は、FlaskとPythonを使用して最初のWebアプリケーションを作成する方法を確認してください。
- 基本的なHTMLの概念の理解。 背景知識については、HTMLを使用してWebサイトを構築する方法チュートリアルシリーズを確認できます。
ステップ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 != 2
でif
ステートメントを使用して、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トピックページをご覧ください。