Flaskアプリケーションでテンプレートを使用する方法
序章
Flask は、Python言語でWebアプリケーションを作成するための便利なツールと機能を提供する軽量のPythonWebフレームワークです。
Webアプリケーションを開発するときは、ビジネスロジックをプレゼンテーションロジックから分離することが重要です。 ビジネスロジックは、ユーザーリクエストを処理し、データベースと通信して適切な応答を構築するものです。 プレゼンテーションロジックは、データをユーザーに提示する方法です。通常、HTMLファイルを使用して応答Webページの基本構造を構築し、CSSスタイルを使用してHTMLコンポーネントのスタイルを設定します。 たとえば、ソーシャルメディアアプリケーションでは、ユーザーがログインしていない場合にのみ表示できるユーザー名フィールドとパスワードフィールドがある場合があります。 ユーザーがログインしている場合は、代わりにログアウトボタンを表示します。 これがプレゼンテーションロジックです。 ユーザーがユーザー名とパスワードを入力すると、Flaskを使用してビジネスロジックを実行できます。リクエストからデータ(ユーザー名とパスワード)を抽出し、資格情報が正しい場合はユーザーにログインするか、エラーメッセージで応答します。 エラーメッセージの表示方法は、プレゼンテーションロジックによって処理されます。
Flaskでは、Jinjaテンプレート言語を使用してHTMLテンプレートをレンダリングできます。 template は、固定コンテンツと動的コンテンツの両方を含むことができるファイルです。 ユーザーがアプリケーション(インデックスページやログインページなど)に何かを要求すると、JinjaではHTMLテンプレートで応答できます。このテンプレートでは、変数など、標準のHTMLでは利用できない多くの機能を使用できます。 if
ステートメント、 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
ファイル:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def hello():
return render_template('index.html')
ファイルを保存して閉じます。
このコードブロックでは、 Flask
クラスとrender_template()関数から flask
パッケージ。 あなたは Flask
名前の付いたFlaskアプリケーションインスタンスを作成するクラス app
. 次に、ビュー関数(HTTP応答を返すPython関数)を定義します。 hello()
を使用して app.route()
通常の関数をビュー関数に変換するデコレータ。 このビュー機能は、 render_template()
と呼ばれるテンプレートファイルをレンダリングする関数 index.html
.
次に、を作成する必要があります index.html
と呼ばれるディレクトリ内のテンプレートファイル templates
あなたの中に flask_app
ディレクトリ。 Flaskは、templatesディレクトリでテンプレートを探します。 templates
、したがって名前は重要です。 あなたが中にいることを確認してください flask_app
ディレクトリを作成し、次のコマンドを実行して、 templates
ディレクトリ:
- mkdir templates
次に、というファイルを開きます index.html
中 templates
編集用のディレクトリ。 名前 index.html
これは標準の必須名ではありません。 あなたはそれを呼ぶことができます home.html
また homepage.html
または必要に応じて他の何か:
- nano templates/index.html
次のHTMLコードを 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.py
あなたの場合)を使用して FLASK_APP
環境変数、およびを設定します FLASK_ENV
環境変数から development
アプリケーションを開発モードで実行し、デバッガーにアクセスします。 これを行うには、次のコマンドを使用します(Windowsでは、 set
それ以外の export
):
- 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()
ファイルが次のようになるように機能します。
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
次のようにファイルを編集します。
<!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>
ファイルを保存して閉じます。
特別なH3見出しを追加しました {{ ... }}
の値を出力する区切り文字 utc_dt
変数。
ブラウザを開き、インデックスページにアクセスします。
http://127.0.0.1:5000/
次の画像のようなページが表示されます。
これで、FlaskアプリケーションでHTMLテンプレートを使用してインデックスページを作成し、テンプレートをレンダリングして、変数値を渡して表示しました。 次に、テンプレートの継承を使用してコードの繰り返しを回避します。
ステップ2—テンプレートの継承を使用する
このステップでは、他のテンプレートと共有できるコンテンツを含むベーステンプレートを作成します。 ベーステンプレートから継承するようにインデックステンプレートを編集します。 次に、アプリケーションの[バージョン情報]ページとして機能する新しいページを作成します。このページで、ユーザーはアプリケーションに関する詳細情報を見つけることができます。
ベーステンプレートには、アプリケーションのタイトル、ナビゲーションバー、フッターなど、他のすべてのテンプレート間で通常共有されるHTMLコンポーネントが含まれています。
まず、という新しいファイルを開きます base.html
テンプレートディレクトリ内で編集する場合:
- nano templates/base.html
あなたの中に次のコードを書いてください 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ページ用です。 <div>
ページのコンテンツ。 (リンクはまだ機能しません。次のステップでは、ページ間をリンクする方法を示します)。
ただし、以下の強調表示されている部分は、Jinjaテンプレートエンジンに固有のものです。
-
{% block title %} {% endblock %}
:タイトルのプレースホルダーとして機能するブロック。 後で他のテンプレートで使用して、全体を書き直すことなく、アプリケーションの各ページにカスタムタイトルを提供します<head>
毎回セクション。 -
{% block content %} {% endblock %}
:子テンプレート(から継承するテンプレート)に応じてコンテンツに置き換えられる別のブロックbase.html
)それを上書きします。
基本テンプレートができたので、継承を使用してそれを利用できます。 を開きます index.html
ファイル:
- nano 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
前のコードブロックのブロック。
このコンテンツブロックには、 <h1>
テキストでタグ付け Index
タイトルブロック内。これにより、元のブロックが置き換えられます。 title
のブロック base.html
テキスト付きのテンプレート Index
完全なタイトルが Index - FlaskApp
. このように、同じテキストが2回繰り返されるのを避けることができます。これは、ページのタイトルと、ベーステンプレートから継承されたナビゲーションバーの下に表示される見出しの両方として機能するためです。
次に、さらにいくつかの見出しがあります。 <h1>
テキストの見出し Hello World!
、 <h2>
見出し、および <h3>
の値を含む見出し utc_dt
変数。
テンプレートの継承により、他のテンプレートにあるHTMLコードを再利用できます(base.html
この場合)必要になるたびに繰り返す必要はありません。
ファイルを保存して閉じ、ブラウザのインデックスページを更新します。 ページは次のようになります。
次に、Aboutページを作成します。 を開きます app.py
新しいルートを追加するファイル:
- nano app.py
ファイルの最後に次のルートを追加します。
# ...
@app.route('/about/')
def about():
return render_template('about.html')
ここでは、 app.route()
と呼ばれるビュー関数を作成するデコレータ about()
. その中で、あなたは呼び出した結果を返します render_template()
で機能する about.html
引数としてのテンプレートファイル名。
ファイルを保存して閉じます。
と呼ばれるテンプレートファイルを開きます about.html
編集用:
- nano 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>
ページのタイトルを兼ねるタグを追加し、 <h3>
アプリケーションに関するいくつかの情報をタグ付けします。
ファイルを保存して閉じます。
開発サーバーが実行されている状態で、ブラウザーを使用して次のURLにアクセスします。
http://127.0.0.1:5000/about
次のようなページが表示されます。
ナビゲーションバーとタイトルの一部がベーステンプレートからどのように継承されているかに注目してください。
これでベーステンプレートが作成され、コードの繰り返しを避けるためにインデックスページとアバウトページで使用されました。 ナビゲーションバーのリンクは、この時点では何もしません。 次のステップでは、ナビゲーションバーのリンクを修正して、テンプレート内のルート間をリンクする方法を学習します。
ステップ3—ページ間のリンク
このステップでは、 url_for()ヘルパー関数を使用してテンプレート内のページ間をリンクする方法を学習します。 ベーステンプレートのナビゲーションバーに2つのリンクを追加します。1つはインデックスページ用で、もう1つは[バージョン情報]ページ用です。
まず、編集用にベーステンプレートを開きます。
- nano 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()
ルートを編集して、リンクが引き続き期待どおりに機能することを保証できます。 The url_for()
関数は、特殊文字のエスケープなどの他の処理も行います。
ファイルを保存して閉じます。
次に、インデックスページに移動して、ナビゲーションバーのリンクを試してください。 期待どおりに機能することがわかります。
使い方を学びました url_for()
テンプレート内の他のルートにリンクする機能。 次に、いくつかの条件ステートメントを追加して、設定した条件に応じてテンプレートに表示される内容を制御し、使用します for
テンプレートをループしてリストアイテムを表示します。
ステップ4—条件とループの使用
このステップでは、 if
テンプレート内のステートメントを使用して、特定の条件に応じて何を表示するかを制御します。 また、使用します for
ループしてPythonリストを調べ、リスト内の各項目を表示します。 リストにコメントを表示する新しいページを追加します。 インデックス番号が偶数のコメントは背景が青色になり、インデックス番号が奇数のコメントは背景が灰色で表示されます。
まず、コメントページのルートを作成します。 あなたの app.py
編集用ファイル:
- nano 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)
上記のルートには、Pythonリストがあります。 comments
4つのアイテムが含まれています。 (これらのコメントは通常、ここで行ったようにハードコーディングされるのではなく、実際のシナリオのデータベースから取得されます。)次のようなテンプレートファイルを返します。 comments.html
最後の行で、という変数を渡します comments
テンプレートファイルへのリストが含まれています。
ファイルを保存して閉じます。
次に、新しい comments.html
内部のファイル templates
編集用のディレクトリ:
- nano 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
行のループ {% for comment in comments %}
の各コメントを確認するには comments
リスト(に保存されます comment
変数)。 コメントをに表示します <p style="font-size: 24px">{{ comment }}</p>
Jinjaで通常変数を表示するのと同じ方法でタグ付けします。 あなたはの終わりを合図します for
を使用してループする {% endfor %}
キーワード。 これはPythonの方法とは異なります for
Jinjaテンプレートには特別なインデントがないため、ループが作成されます。
ファイルを保存して閉じます。
開発サーバーが実行されている状態で、ブラウザーを開き、コメントページにアクセスします。
http://127.0.0.1:5000/comments
次のようなページが表示されます。
今、あなたは使用します if
背景が灰色の奇数のインデックス番号のコメントと、背景が青色の偶数のインデックス番号のコメントを表示することによる、テンプレートの条件付きステートメント。
あなたの comments.html
編集用のテンプレートファイル:
- nano 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
行のステートメント {% if loop.index % 2 == 0 %}
. ループ変数は、現在のループに関する情報にアクセスできる特別なJinja変数です。 ここで使用します loop.index
現在のアイテムのインデックスを取得します。 1
、 いいえ 0
Pythonリストのように。
The if
ここでのステートメントは、インデックスが %
オペレーター。 インデックス番号を除算する余りをチェックします 2
; 残りが 0
これは、インデックス番号が偶数であることを意味します。それ以外の場合、インデックス番号は奇数です。 あなたは {% set %}
と呼ばれる変数を宣言するタグ bg_color
. インデックス番号が偶数の場合は青みがかった色に設定し、インデックス番号が奇数の場合は青みがかった色に設定します。 bg_color
灰色に可変。 次に、 bg_color
の背景色を設定する変数 <div>
コメントを含むタグ。 コメントのテキストの上に、 loop.index
現在のインデックス番号を <p>
鬼ごっこ。
ファイルを保存して閉じます。
ブラウザを開き、コメントページにアクセスします。
http://127.0.0.1:5000/comments
新しいコメントページが表示されます。
これは、使用方法のデモンストレーションでした if
声明。 しかし、あなたはまた、特別なものを使用することによって同じ効果を達成することができます loop.cycle()
ジンジャヘルパー。 これを示すために、 comments.html
ファイル:
- nano 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番目のコメントを除くすべてのコメントを表示するには、 if
条件付きのステートメント loop.index != 2
2番目のコメントを除外します。
コメントテンプレートを開きます。
- nano 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()
物事を簡単にするヘルパー、そして残りは変更されません。 あなたは終わります if
使用するステートメント {% endif %}
.
ファイルを保存して閉じます。
コメントページを更新すると、2番目のコメントが表示されていないことがわかります。
次に、ナビゲーションバーのコメントページにユーザーを誘導するリンクを追加する必要があります。 編集用にベーステンプレートを開きます。
- nano templates/base.html
の内容を編集する <nav>
新しいタグを追加して <a>
それへのリンク:
<!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リストを調べてリスト内の各アイテムを表示するためのループ、そしてあなたは特別なことについて学びました loop
Jinjaの変数。 次に、Jinjaフィルターを使用して、変数データの表示方法を制御します。
ステップ5—フィルターの使用
このステップでは、テンプレートでJinjaフィルターを使用する方法を学習します。 を使用します upper
前の手順で追加したコメントを大文字に変換するためのフィルターを使用します。 join
一連の文字列を1つの文字列に結合するためのフィルターを使用し、信頼できるHTMLコードをエスケープせずにレンダリングする方法を学習します。 safe
フィルター。
まず、コメントページのコメントを大文字に変換します。 を開きます comments.html
編集用のテンプレート:
- nano 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
次のように編集します。
{% 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>
内のすべてのコメントに参加するタグ comments
を使用してリスト join()
フィルター。
ファイルを保存して閉じます。
コメントページを更新すると、次のようなページが表示されます。
ご覧のとおり、 comments
リストは、パイプ記号で区切られたコメントとともに表示されます。これは、に渡したものです。 join()
フィルター。
もう1つの重要なフィルターは safe
フィルタ。ブラウザで信頼できるHTMLをレンダリングできます。 これを説明するために、HTMLタグを含むテキストをコメントテンプレートに追加します。 {{ }}
ジンジャ区切り文字。 実際のシナリオでは、これはサーバーからの変数として提供されます。 次に、編集します join()
であるための引数 <hr>
パイプ記号の代わりにタグを付けます。
コメントテンプレートを開きます。
- nano 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
フィルター:
{% 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 | join(" <hr> ") | safe }}</p>
. 各フィルターは、前のフィルターの結果に適用されます。
ファイルを保存して閉じます。
コメントページを更新すると、HTMLタグが期待どおりにレンダリングされていることがわかります。
警告: safe
不明なデータソースからのHTMLをフィルタリングすると、アプリケーションがXSS攻撃にさらされる可能性があります。 レンダリングするHTMLが信頼できるソースからのものでない限り、使用しないでください。
詳細については、組み込みのJinjaフィルターのリストを確認してください。
これで、Jinjaテンプレートでフィルターを使用して変数値を変更する方法を学習しました。 次に、Bootstrapツールキットを統合してアプリケーションのスタイルを設定します。
ステップ6—ブートストラップの統合
このステップでは、Bootstrapツールキットを使用してアプリケーションのスタイルを設定する方法を学習します。 ベーステンプレートから継承するすべてのページに表示されるブートストラップナビゲーションバーをベーステンプレートに追加します。
Bootstrapツールキットは、アプリケーションのスタイルを設定して、視覚的に魅力的なものにするのに役立ちます。 また、レスポンシブWebページをWebアプリケーションに組み込んで、これらの目標を達成するために独自のHTML、CSS、およびJavaScriptコードを記述しなくてもモバイルブラウザーで適切に機能するようにするのにも役立ちます。
Bootstrapを使用するには、Bootstrapをベーステンプレートに追加して、他のすべてのテンプレートで使用できるようにする必要があります。
あなたの base.html
テンプレート、編集用:
- nano 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>
上記のコードのほとんどは、それを使用するために必要なブートストラップボイラープレートです。 いくつかのメタタグ、ブートストラップCSSファイルへのリンクがあります <head>
セクション、および下部にオプションのJavaScriptへのリンクがあります。 コードの強調表示された部分には、前の手順で説明したJinjaコードが含まれています。 特定のタグとCSSクラスを使用して、各要素の表示方法をBootstrapに指示する方法に注目してください。
の中に <nav>
上記のタグ、あなたは <a>
クラスのタグ navbar-brand
、ナビゲーションバーのブランドリンクを決定します。 内部 <ul class="navbar-nav">
タグ、あなたは中に通常のナビゲーションバーアイテムを持っています <a>
のタグ <li>
鬼ごっこ。
これらのタグとCSSクラスの詳細については、ブートストラップコンポーネントを参照してください。
ファイルを保存して閉じます。
開発サーバーが実行されている状態で、ブラウザーでインデックスページを開きます。
http://127.0.0.1:5000/
次のようなページが表示されます。
Bootstrapコンポーネントを使用して、すべてのテンプレートのFlaskアプリケーションでアイテムのスタイルを設定できるようになりました。
結論
これで、FlaskWebアプリケーションでHTMLテンプレートを使用する方法がわかりました。 サーバーからテンプレートにデータを渡すために変数を使用し、繰り返しを避けるためにテンプレートの継承を採用し、次のような要素を組み込んだ if
条件文と for
ループし、異なるページ間でリンクされます。 テキストを変更して信頼できるHTMLを表示するためのフィルターについて学び、Bootstrapをアプリケーションに統合しました。
Flaskの詳細については、Flaskトピックページをご覧ください。