※このページではアフィリエイト広告を利用しています

【Flask入門】Jinja2を使って動的コンテンツをレンダリングする方法

Python

Flaskは、Webアプリケーションの構築を簡素化するために、Jinja2という強力なテンプレートエンジンを使用しています。Jinja2を使うことで、HTMLの静的な部分と動的な部分を分け、動的にコンテンツを生成することができます。

この記事では、FlaskのJinja2テンプレートエンジンを使い、動的にコンテンツをレンダリングする方法を学び、Webページのデザインを柔軟にする方法を紹介しています。


スポンサーリンク
スポンサーリンク

Jinja2とは?

Jinja2は、Python用のテンプレートエンジンで、Flaskのデフォルトのテンプレートエンジンとして使用されています。Jinja2は、PythonのコードをHTMLに埋め込んで動的なコンテンツを生成することができ、Webアプリケーションに柔軟性と効率性が出ます。

Jinja2の主な特徴:

  • 動的コンテンツの生成: PythonのデータをHTMLに挿入できる
  • 制御構造: ループや条件分岐が可能
  • フィルターと変数: データの加工や変換を簡単に行える
  • テンプレートの継承: ベースとなるHTML構造を共通化して再利用できる

FlaskでJinja2を使う方法

基本的な使い方

FlaskでJinja2を使用するためには、render_template()関数を使います。この関数を使うことで、PythonのデータをHTMLテンプレートに渡して、動的なWebページを生成できます。

例: index.htmlテンプレートを使って動的コンテンツを表示

まず、Flaskアプリケーションのコードを以下のように作成します。

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
    # 渡すデータ
    user_name = 'John'
    return render_template('index.html', name=user_name)

if __name__ == '__main__':
    app.run(debug=True)

HTMLテンプレートの作成

templatesというフォルダを作成し、その中にindex.htmlというテンプレートファイルを作成します。Flaskは、render_template()を呼び出すことで、templatesフォルダ内のHTMLファイルをレンダリングします。

index.htmlの内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Welcome</title>
</head>
<body>
    <h1>Hello, {{ name }}!</h1>
</body>
</html>

このHTMLでは、{{ name }}という部分がJinja2のテンプレートタグです。この部分には、Flaskから渡されたnameという変数が挿入されます。

結果

この状態でFlaskアプリケーションを実行し、ブラウザでhttp://127.0.0.1:5000/にアクセスすると、ページには「Hello, John!」と表示されます。Flaskがrender_template()を使って、name変数をindex.htmlに渡し、その値を表示しています。


Jinja2の制御構造

Jinja2は、条件分岐やループなど、様々な制御構造があります。これにより、動的なWebページをより柔軟に作成できます。

条件分岐 (if文)

Jinja2では、{% if condition %}...{% endif %}を使って条件分岐を行うことができます。

例: ユーザーのログイン状態を表示

@app.route('/')
def home():
    logged_in = True
    return render_template('index.html', logged_in=logged_in)

index.htmlで条件分岐を使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Welcome</title>
</head>
<body>
    {% if logged_in %}
        <h1>Welcome, User!</h1>
    {% else %}
        <h1>Please log in.</h1>
    {% endif %}
</body>
</html>

この例では、logged_inTrueの場合、「Welcome, User!」と表示され、Falseの場合は「Please log in.」と表示されます。

結果

ループ (for文)

Jinja2では、{% for item in collection %}...{% endfor %}を使ってリストや辞書をループ処理できます。

例: リストのアイテムを表示

@app.route('/')
def home():
    items = ['Apple', 'Banana', 'Cherry']
    return render_template('index.html', items=items)

index.htmlでループを使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Items</title>
</head>
<body>
    <h1>Items List:</h1>
    <ul>
        {% for item in items %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
</body>
</html>

この例では、itemsリストの各要素が<li>タグとして表示されます。

結果


Jinja2のフィルターと変数の操作

Jinja2では、データを表示する際にフィルターを使って加工することができます。

フィルターの使用

例えば、文字列を大文字に変換したり、日付をフォーマットしたりすることができます。

例: 文字列を大文字に変換

@app.route('/')
def home():
    message = 'hello, world'
    return render_template('index.html', message=message)

index.htmlでフィルターを使う

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Message</title>
</head>
<body>
    <h1>{{ message|upper }}</h1> <!-- upperフィルターを使って大文字に -->
</body>
</html>

この場合、messageupperフィルターによって大文字に変換され、HELLO, WORLDと表示されます。

結果


テンプレートの継承

Jinja2では、テンプレートの継承を使って、共通のレイアウトを作成し、異なる部分だけを動的に変更することができます。これにより、コードの重複を避け、メンテナンス性を向上させることができます。

以下では、Flaskのアプリケーションを作成し、base.htmlという共通のベーステンプレートを作成し、そのテンプレートをhome.htmlという個別のページで継承して使用します。

Flaskアプリケーション(Pythonプログラム)

まず、Flaskアプリケーションを作成します。このアプリケーションでは、homeというURLにアクセスすると、home.htmlがレンダリングされるようにします。

from flask import Flask, render_template

app = Flask(__name__)

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

if __name__ == '__main__':
    app.run(debug=True)

ベーステンプレートを作成

次に、すべてのページで共通するHTMLのレイアウト(ヘッダー、フッターなど)を定義したbase.htmlテンプレートを作成します。このテンプレートは、他のページで継承されて、内容が動的に変更されます。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}My Website{% endblock %}</title>
</head>
<body>
    <header>
        <h1>Welcome to My Website</h1>
        <nav>
            <ul>
                <li><a href="/">Home</a></li>
                <li><a href="/about">About</a></li>
            </ul>
        </nav>
    </header>

    <div>
        {% block content %}{% endblock %}
    </div>

    <footer>
        <p>&copy; 2023 My Website</p>
    </footer>
</body>
</html>

継承を使ったページ作成

次に、home.htmlというページでベーステンプレートを継承します。

{% extends 'base.html' %}

{% block title %}Home Page{% endblock %}

{% block content %}
    <h2>This is the home page</h2>
    <p>Welcome to my website!</p>
{% endblock %}

これにより、home.htmlbase.htmlのレイアウトを継承し、titlecontentだけを動的に変更しています。

結果

次にaboutページを作成してみます。ここでもbase.htmlのレイアウトを継承します。

Flaskアプリケーションに/aboutルートを追加する

app.py/aboutルートを追加します。これにより、/aboutにアクセスしたときに表示されるコンテンツを定義することができます。

Flaskアプリケーションに/aboutルートを追加

from flask import Flask, render_template

app = Flask(__name__)

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

# /aboutルートを追加
@app.route('/about')
def about():
    return render_template('about.html')

if __name__ == '__main__':
    app.run(debug=True)

about.htmlテンプレートを作成する

/aboutルートにアクセスしたときに表示するHTMLテンプレート(about.html)を作成します。templatesフォルダ内に新しいabout.htmlファイルを作成し、必要なコンテンツを追加します。

templates/about.htmlの内容:

{% extends 'base.html' %}

{% block title %}About Page{% endblock %}

{% block content %}
    <h2>About Us</h2>
    <p>Welcome to the About page of our website. Here you can learn more about our mission and goals.</p>
{% endblock %}

ディレクトリ構成

プロジェクトのディレクトリ構成は次のようになります:

/your-flask-app
    /templates
        base.html
        home.html
        about.html  <-- 新たに追加したabout.html
    app.py

Flaskアプリケーションを再起動

app.pyに変更を加えた後、Flaskサーバーを再起動して新しいルートが反映されるようにします。

python app.py

結果

まとめ

Jinja2は、FlaskでのWeb開発をより柔軟に、効率的にするために便利です。テンプレートエンジンを使うことで、HTMLを動的に生成し、データを埋め込んで表示することができます。また、制御構造やフィルターを使うことで、さらに高度な処理も可能になります。テンプレートの継承を使えば、共通のレイアウトを再利用し、コードの重複を減らすことができます。

これでFlaskとJinja2を使ったWebアプリケーションの開発がよりスムーズに進められるようになります!

タイトルとURLをコピーしました