スキップしてメイン コンテンツに移動

Jinja2の使い方を紹介。Flask+Jinja2

この記事では、FlaskのテンプレートエンジンであるJinja2の使い方について、解説します。Jinja2はPythonのWebサービスでよく用いられるため、覚えておいて損はないです。

もしPythonのフレームワークであるDjangoを経験していれば、構文がよく似ているため、すんなりと理解することが出来ると思います。

enter image description here

Jinja2とは

Jinja2は、Python用のテンプレートエンジンの1つ。Pythonの有名なフレームワークである、Djangoのテンプレートエンジンに構文がよく似ています。Jinja2は基本的にHTMLやXML生成に使われるが、どのような文書でも生成できます。(例えばソースコードやMarkdownなど)

Jinja2は、Flask内のテンプレートエンジンとして組み込まれています。そのため、Flaskの環境があれば、追加のインスール不要でJinja2が使えます。

ちなみにJinja2 は、 「じんじゃ(神社)」 と読むそうです。

はじめに

FlaskでJinja2を使用する場合は、Jinja2のテンプレートファイルを、templatesディレクトリに作成します。templates以外のフォルダにJinja2のテンプレートを作成しても、Flaskは認識してくれませんのでご注意を。

project_root
├── app.py
└── templates
    ├── index.html
    └── about.html

Jinja2の基本的な使い方

ほほ公式のままですが、下記がJinja2のテンプレートのサンプルです。

<title>{{title}}</title>
<ul>
{% for user in users %}
  <li><a href="{{ user.url }}">{{ user.username }}</a></li>
{% endfor %}
</ul>

テンプレート構文

Jinja2テンプレートの基本的な構文です。

構文 説明
{% ... %} ステートメント
{{ ... }}
{# ... #} コメント
# ... ## 行ステートメント

Jinja2にパラメータを渡す

render_template()に名前付き引数を指定すると、Jinja2のテンプレートにパラメーターを渡すことができます。パラメータを渡す、いくつかのサンプルコードを紹介します。

文字列(str)を渡す

[Python]

from flask import render_template

@app.route("/index")
def index():
  msg = 'Hello'
  return render_template('index.html', msg = msg)

[Teamplate]

<div>
  <p>{{message}}</p>
</div>

辞書(dict)を渡す

[Python]

from flask import render_template

@app.route("/index")
def index():
  user = { 'name': '山田太郎', 'age': 20 }
  return render_template('index.html', user = user)

[Teamplate]

<div>
  <p>ユーザ名: {{user.name}}</p>
  <p>年齢: {{user.age}}</p>
</div>

クラスを渡す

[Python]

from flask import render_template

@app.route("/index")
def index():
  user = User()
  user.name = '山田太郎'
  user.age = 200
  return render_template('index.html', user = user)

[Teamplate]

<div>
  <p>ユーザ名: {{user.name}}</p>
  <p>年齢: {{user.age}}</p>
</div>

Jinja2に複数のパラメータを渡すには

Jinja2のテンプレートに複数のパラメータを渡すには、Pythonのrender_template関数呼び出し時に、名前付き引数を複数指定してやるだけです。

[Python]

from flask import render_template

@app.route("/index")
def index():
  user = User()
  user.name = '山田太郎'
  user.age = 200
  return render_template('index.html', msg = "Hello", user = user)

[Teamplate]

<p>{{msg}}</p>
<div>
  <p>ユーザ名: {{user.name}}</p>
  <p>年齢: {{user.age}}</p>
</div>

Jinja2のテンプレートで分岐する(if)

if文は、Pythonの記法とほとんど同じです。Pythonとの違いとして、行末のコロン(:)が不要なことと、if文を終了するときは、{% endif %}と書きます。

{% if user.age < 20 %}
  <p>未成年</p>
{% elif user.age >= 20 and user.age <= 60 %}
  <p>現役</p>
{% else %}
  <p>シルバー</p>
{% endif %}

Jinja2のテンプレートで繰り返し(for)

<select>
{% for user in users %}
  <option value="{{user.id}}" {{'selected' if user.id == sel_id else ''}}>{{user.name}}</option>
{% endfor %}
</select>

エスケープ(Jinja2の"{{", "{%"をエスケープ)

Jinja2テンプレートの特殊文字である"{{"や "{%“を、文字として扱いたい場合は、{% raw %}ブロックを使用します。{% raw %}ブロック内に書かれた内容は、すべて文字として扱われるため、”{{"や "{%"などの特殊文字を文字として表示させる事ができます。

{% raw %}
  <ul>
    {% for item in seq %}
      <li>{{ item }}</li>
    {% endfor %}
  </ul>
{% endraw %}

Jinja2 のテンプレートを継承する

ページヘッダーや、サイドメニューなど、どのページでも共通している部分を、共通のレイアウトとして作成しておき、そのレイアウトを継承させた、子テンプレートを作成できます。

継承を行なった子テンプレートは、共通部分のHTMLを記述する必要がなく、個別部分のHTMLだけを記述します。これにより、もし共通部分のレイアウトに手が入る場合、共通のレイアウトを1箇所修正するだけで済むため、保守性がよくなります。

[base.html]

<!DOCTYPE html>
<html lang="ja">
<head>
  <title>{% block title %}{% endblock %} - サンプルサイト</title>
  {% block head %}
  <link rel="stylesheet" href="style.css" />
  {% endblock %}
</head>
<body>
<!-- 共通ヘッダ -->
<header>
   <h1>{% block title %}{% endblock %}</h1>
</header>
<!-- コンテンツ部分 -->
<div id="content">
  {% block body %}
  {% endblock %}
</div>
</body>
</html>

[子テンプレート]

{% extends "base.html" %}
{% block title %}ページタイトル{% endblock %}
 
{% block head %}
    {{ super() }}
    <style type="text/css">
        .message { color: #f00; }
    </style>
{% endblock %}
         
{% block content %}
  <p class="message">
    Welcome to my awesome homepage.
  </p>
{% endblock %}

Jinja2 のインクルード機能

Jinja2のインクルード(include)機能を使うと、継承を使うほどでもないけど、ページで共通している部分をコンポーネント化できます。例えば、ページングを行うページネーションなどをコンポーネント化しておくと、インクルード機能で複数の画面から使用できて便利です。

[pagger.html]


```html
<!--前のページ-->
{% if has_previous %}
<a  href="mypage?page={{ previous_page }}">前</a>
{% endif %}

<!--ページ番号-->
<span>{{ page.number }} / {{ page.paginator.num_pages }}</span>

<!--次のページ-->
{% if has_next %}
<a  href="mypage?page={{ next_page }}">次</a>
{% endif %}

上で作成したテンプレートはincludeで読み込みます。

<nav>
    <!--上で作成した部品を読み込む-->
    {% include "pagger.html" %}
</nav>

コメント

このブログの人気の投稿

axiosの使い方まとめ (GET/POST/例外処理)

axiosの使い方まとめ (GET/POST/例外処理)最近何かとよく使うJavaScriptでAJAX通信を行うaxiosについて、簡単に使い方をまとめました。GETリクエストをaxiosで送るまずはGETリクエストをaxiosで送る方法です。const res =await axios.get('/users') console.log(res.data)分割代入の記法を使うと、以下のようにも書けますconst{data}=await axios.get('/users') console.log(data)クエリパラメータ (URLパラメータ)を指定クエリパラメータを指定する方法は2つあります。1つ目は、axios.getに指定するURLに直接記述する方法です。axios.get('/user?id=123')2つめは、axios.getの第2引数に、オプション指定する方法です。axios.get('/user',{ params:{ id:123}})POSTリクエストをaxiosで送る次はPOSTリクエストをaxiosで送る方法です。JSON形式でPOSTするJSON形式でPOSTする場合は、axios.postの第2引数に、送信するデータをJavaScriptオブジェクトで指定します。const res =await axios.post('/user',{ id:123, name:'Yamada Tarou'})application/x-www-form-urlencoded形式でPOSTするapplication/x-www-form-urlencoded形式でPOSTする場合は、URLSearchParamsを使います。var params =newURLSearchParams() params.append('id',123) params.append('name','Yamada Tarou')const res =await axios.post('/user', params)スポンサーリンク axios でファイルをアップロードする画像などのファイルを、…

[VB, C#] Windows 8, Window 10 で ImeModeが制御できない問題を解決する

[VB, C#] Windows 8, Window 10 で ImeModeが制御できない問題を解決するタイトルの通りですが、Windows 8 以降では Windows Form アプリケーションで、コントロールの ImeMode に Katakana や KatakanaHalf を設定しても、カタカナになってくれません。なぜ ImeMode が効かないのか?Windows 8 以降、IME Mode の切り替えは、ユーザー単位で切り替わるようになった為、アプリから IME Mode 制御が出来ないようになりました。
(IME をON にした場合、常に ひらがな モードになます)※ Windows 7までは、IME Modeの切り替えはアプリ単位で行われていた為、問題なくアプリから IME制御が行えました。スポンサーリンク 対処方法Windows 8 以降、IMEの制御は、InputScope クラスの利用が推奨されています。
しかし、InputScope クラスは、WPF、Windows ストアアプリでしか使えない為、Windows Formアプリでは使用できません。
(Windows Form はもう使うな!という事でしょうか (涙) )結論としては、コントールパネルの設定で、IMEの制御をユーザ単位から アプリ単位に変更する事ができます。
これで、Windows Formアプリでも 従来通りIMEの制御を行う事が出来ます。おわりにこの方法だと、アプリをインストールする端末すべてに設定が必要となり、とっても面倒です。。。
しかし、今の所これしか方法がない状態です。
これからは Windows Formではなく、WPFや Windows ストアアプリで作れという事ですかね (^^;)

MailKitの使い方! エンコーディング指定や添付ファイをメールで送信する方法[C#/VB Tips]

MailKitの使い方! エンコーディング指定や添付ファイをメールで送信する方法[C#/VB Tips]MailKitを使ってメールを送るサンプルコードです。(C#)UTF8/iso-2022-jpのエンコーディング指定、GMail/YahooのSMTPサーバで送るなど、4つのサンプルコードでMailKitの使い方を紹介します。MailKitって何?2017年に.NET標準のSystem.Net.Mail.SmtpClientが廃止予定となり、Microsoftより今後はオープンソースライブラリである、MailKitに置き換えるとアナウンスがありました。既にSmtpClientは非推奨になっており、今後は廃止されていきます。現在、SmtpClientを使用したソースコードには、Visual StudioからMailKitを使うよう警告が出るようになっています。さっそく、MailKitを使ってメールを送信するサンプルコードを作っていきます。UTF8でメールを送信文字エンコーディングを、UTF8でメールを送信するサンプルコードです。
MailKitは、デフォルトの文字エンコーディングがUTF8なっている為、シンプルなコードでメールを送信する事ができます。var host ="<smtp server name>"; var port =25;// or 587using(var smtp =new MailKit.Net.Smtp.SmtpClient()){//SMTPサーバに接続する smtp.Connect(host, port, MailKit.Security.SecureSocketOptions.Auto);//認証が必要な場合は、以下のコメントを解除//smtp.Authenticate("<id>", "<password>");//送信するメールを作成する var mail =new MimeKit.MimeMessage(); var builder =new MimeKit.BodyBuilder(); mail.From.Add(new MimeKit.MailboxAddress("",&quo…