[Python] Bottleでテンプレートを使用する方法
Bottleは軽量なPythonのWebフレームワークで、テンプレートエンジンを使用してHTMLを動的に生成できます。
bottle
にはデフォルトでSimpleTemplateEngine
が組み込まれており、{{変数}}
の形式で変数を埋め込むことが可能です。
テンプレートを使用するには、bottle.template()関数
を使います。
テンプレートファイルは.tpl
形式で保存し、@route
デコレータでルートを定義した後、template()関数
でテンプレートをレンダリングします。
簡単な概要
Bottleは、Pythonで書かれたシンプルで軽量なWebフレームワークです。
特に小規模なアプリケーションやプロトタイプの開発に適しており、単一のファイルで完結するため、導入が非常に簡単です。
Bottleは、RESTfulなルーティング、テンプレートエンジン、静的ファイルの提供など、Webアプリケーションに必要な基本機能を備えています。
さらに、Bottleは依存関係が少なく、他のライブラリやフレームワークと組み合わせて使用することも容易です。
これにより、開発者は迅速にアプリケーションを構築し、デプロイすることが可能です。
特に、学習や実験を目的としたプロジェクトにおいて、そのシンプルさと柔軟性が評価されています。
Bottleでテンプレートを使用する準備
テンプレートエンジンの概要
テンプレートエンジンは、HTMLなどの文書を動的に生成するためのツールです。
プログラム内でデータを埋め込むことにより、ユーザーに対してカスタマイズされたコンテンツを提供できます。
Bottleでは、デフォルトで SimpleTemplate
というシンプルなテンプレートエンジンが使用されており、Pythonの文法に似た構文で記述できます。
これにより、開発者は直感的にテンプレートを作成し、データを埋め込むことが可能です。
Bottleにおけるテンプレートの役割
Bottleにおけるテンプレートは、主に以下の役割を果たします。
役割 | 説明 |
---|---|
コンテンツの分離 | ビジネスロジックと表示ロジックを分けることで、コードの可読性を向上させる。 |
再利用性の向上 | 同じテンプレートを複数の場所で使い回すことができ、メンテナンスが容易になる。 |
動的コンテンツ生成 | ユーザーの入力やデータベースの情報に基づいて、動的にHTMLを生成する。 |
テンプレートファイルの作成方法
Bottleでテンプレートを使用するには、まずテンプレートファイルを作成します。
通常、.tpl
や.html
の拡張子を持つファイルを作成し、HTMLの中に埋め込む変数や制御構文を記述します。
以下は、基本的なテンプレートファイルの例です。
<!-- example.tpl -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ heading }}</h1>
<p>{{ message }}</p>
</body>
</html>
Bottleのテンプレートディレクトリの指定
Bottleでは、テンプレートファイルを格納するディレクトリを指定する必要があります。
これにより、Bottleは指定された場所からテンプレートを読み込むことができます。
以下のように、Bottle
オブジェクトを作成する際に、template_path
を設定します。
from bottle import Bottle, run, template
app = Bottle()
app.template_path.insert(0, 'templates') # テンプレートディレクトリを指定
# ルートエンドポイントの定義
@app.route('/')
def index():
return template('example.tpl', title='サンプル', heading='こんにちは', message='Bottleのテンプレートを使用しています。')
run(app, host='localhost', port=8080)
この例では、templates
というディレクトリにexample.tpl
ファイルを格納し、Bottleがそのテンプレートを使用できるように設定しています。
Bottleでテンプレートを使った基本的な例
template()関数の使い方
Bottleでは、template()関数
を使用してテンプレートをレンダリングします。
この関数は、テンプレートファイル名と、必要に応じてテンプレートに渡すデータを引数として受け取ります。
以下は、template()関数
の基本的な使い方の例です。
from bottle import Bottle, run, template
app = Bottle()
@app.route('/')
def index():
return template('example.tpl', title='サンプル', heading='こんにちは', message='Bottleのテンプレートを使用しています。')
run(app, host='localhost', port=8080)
この例では、example.tpl
というテンプレートファイルを指定し、title
、heading
、message
という変数をテンプレートに渡しています。
テンプレートファイルの構造
テンプレートファイルは、HTMLの基本構造を持ちながら、埋め込む変数や制御構文を含むことができます。
以下は、example.tpl
の構造の例です。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ heading }}</h1>
<p>{{ message }}</p>
</body>
</html>
このテンプレートでは、{{ title }}
、{{ heading }}
、{{ message }}
が変数として埋め込まれています。

これらは、template()関数
で渡されたデータに基づいて動的に置き換えられます。
変数の埋め込み方法
テンプレート内で変数を埋め込むには、{{ variable_name }}
という形式を使用します。
例えば、以下のように変数を埋め込むことができます。
<p>ようこそ、{{ user_name }}さん!</p>
この場合、user_name
という変数がtemplate()関数
で渡されると、テンプレート内でその値が表示されます。
テンプレート内での制御構文(if文、for文)
Bottleのテンプレートでは、制御構文を使用して条件分岐やループ処理を行うことができます。
以下は、if
文とfor
文の例です。
if文の例
% if is_logged_in:
<p>ログインしています。</p>
% else
<p>ログインしていません。</p>
% end
この例では、is_logged_in
という変数がTrue
の場合は「ログインしています。」と表示され、False
の場合は「ログインしていません。」と表示されます。
for文の例
<ul>
% for item in item_list:
<li>{{ item }}</li>
% end
</ul>
この例では、item_list
というリストの各要素をループ処理し、リスト項目として表示します。
これにより、動的に生成されたリストを簡単に作成できます。
テンプレートにデータを渡す方法
Python側でのデータ準備
Bottleでテンプレートにデータを渡すためには、まずPython側で必要なデータを準備します。
データは辞書形式で用意することが一般的です。
以下は、ユーザー情報を含むデータの準備の例です。
from bottle import Bottle, run, template
app = Bottle()
@app.route('/')
def index():
user_data = {
'user_name': '太郎',
'age': 25,
'hobbies': ['読書', '映画鑑賞', '旅行']
}
return template('example.tpl', **user_data)
run(app, host='localhost', port=8080)
この例では、user_data
という辞書にユーザー名、年齢、趣味のリストを格納しています。
**user_data
を使うことで、辞書のキーが変数名としてテンプレートに渡されます。
template()関数でのデータ渡し
template()関数
を使用して、準備したデータをテンプレートに渡します。
先ほどの例では、**user_data
を使って、辞書の内容を展開して渡しています。
これにより、テンプレート内で各変数を直接使用できるようになります。
return template('example.tpl', **user_data)
このようにすることで、user_name
、age
、hobbies
といった変数がテンプレート内で利用可能になります。
テンプレート内でのデータの表示
テンプレート内では、渡されたデータを埋め込むことで、動的にコンテンツを生成できます。
以下は、example.tpl
の一部で、データを表示する方法の例です。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ユーザー情報</title>
</head>
<body>
<h1>{{ user_name }}さんのプロフィール</h1>
<p>年齢: {{ age }}歳</p>
<h2>趣味</h2>
<ul>
% for hobby in hobbies:
<li>{{ hobby }}</li>
% end
</ul>
</body>
</html>
このテンプレートでは、{{ user_name }}
、{{ age }}
、および{% for hobby in hobbies %}
を使用して、Python側で準備したデータを表示しています。
これにより、ユーザーのプロフィール情報が動的に生成され、ブラウザに表示されます。
テンプレートのカスタマイズ
テンプレートの継承
Bottleでは、テンプレートの継承を使用して、共通のレイアウトを持つ複数のテンプレートを効率的に管理できます。
親テンプレートを作成し、子テンプレートでその内容を拡張することで、コードの重複を避けることができます。
以下は、親テンプレートの例です。
<!-- base.html -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
<header>
<h1>私のウェブサイト</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
<p>© 2023 私のウェブサイト</p>
</footer>
</body>
</html>
子テンプレートでは、base.tpl
を継承し、block content
を埋めることができます。
<!-- child.html -->
{% extends "base.html" %}
{% block content %}
<h2>こんにちは、{{ user_name }}さん!</h2>
<p>あなたの年齢は{{ age }}歳です。</p>
{% endblock %}
これらのテンプレートを配置して、以下のプログラムを実行すると、親テンプレートを継承したページを表示できます。
from bottle import Bottle, run
from bottle import jinja2_template as template
app = Bottle()
# ルートエンドポイントの定義
@app.route('/')
def index():
# 表示するユーザーデータ
user_data = {
'title': 'ユーザー情報',
'user_name': '太郎',
'age': 25
}
# child.html を使ってテンプレートをレンダリング
return template('child.html', **user_data)
# アプリケーションを起動
run(app, host='localhost', port=8080)

テンプレートのパーシャル(部分テンプレート)
パーシャルテンプレートは、再利用可能な部分を別のテンプレートファイルとして切り出す方法です。
これにより、コードの重複を減らし、メンテナンスを容易にします。
from bottle import Bottle, run
from bottle import jinja2_template as template
app = Bottle()
@app.route('/')
def index():
return template('main.tpl')
run(app, host='localhost', port=8080)
例えば、ナビゲーションバーをパーシャルとして作成することができます。
<!-- navbar.tpl -->
<nav>
<ul>
<li><a href="/">ホーム</a></li>
<li><a href="/about">アバウト</a></li>
<li><a href="/contact">お問い合わせ</a></li>
</ul>
</nav>
このパーシャルを他のテンプレートで使用するには、template()関数
を使って読み込みます。
<!-- main.tpl -->
{% include "navbar.tpl" %}
<h1>メインコンテンツ</h1>
<p>ここにメインの内容が入ります。</p>

テンプレートでのフィルタリング
Bottleのテンプレートでは、フィルタリングを使用してデータを加工することができます。
例えば、文字列を大文字に変換したり、リストの要素を結合したりすることが可能です。
以下は、フィルタリングの例です。
<p>大文字: {{ user_name | upper }}</p> <!-- user_nameを大文字に変換 -->
<p>趣味: {{ hobbies | join(", ") }}</p> <!-- hobbiesリストをカンマ区切りで表示 -->
このように、フィルタを使うことで、テンプレート内でデータを簡単に加工できます。
カスタムフィルタの作成
Bottleでは、独自のカスタムフィルタを作成することもできます。
これにより、特定のデータ処理を簡単に行うことができます。
以下は、カスタムフィルタの作成方法の例です。
from bottle import Bottle, run, template
app = Bottle()
# カスタムフィルタの定義
def reverse_string(s):
return s[::-1]
# フィルタを登録
app.template_filters['reverse'] = reverse_string
@app.route('/')
def index():
return template('example.tpl', user_name='太郎')
run(app, host='localhost', port=8080)
この例では、reverse_string
というカスタムフィルタを作成し、app.template_filters
に登録しています。
テンプレート内でこのフィルタを使用することで、文字列を逆順に表示できます。
<p>逆順: {{ user_name | reverse }}</p> <!-- user_nameを逆順に表示 -->
このように、カスタムフィルタを使うことで、テンプレート内でのデータ処理を柔軟に行うことができます。
Bottleでのフォーム処理とテンプレート
フォームの作成と表示
Bottleを使用してフォームを作成するには、HTMLの<form>
タグを使用します。
以下は、ユーザー名と年齢を入力するシンプルなフォームの例です。
テンプレートファイルにフォームを追加します。
<!-- form.tpl -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ユーザー情報フォーム</title>
</head>
<body>
<h1>ユーザー情報を入力してください</h1>
<form action="/submit" method="post">
<label for="user_name">ユーザー名:</label>
<input type="text" id="user_name" name="user_name" required><br><br>
<label for="age">年齢:</label>
<input type="number" id="age" name="age" required><br><br>
<input type="submit" value="送信">
</form>
</body>
</html>
このフォームは、ユーザー名と年齢を入力するためのフィールドを持ち、送信ボタンをクリックすると/submit
エンドポイントにデータがPOSTされます。
フォームデータの受け取り
フォームから送信されたデータは、Bottleのrequest
オブジェクトを使用して受け取ります。
以下は、フォームデータを受け取るためのエンドポイントの例です。
from bottle import Bottle, run, template, request
app = Bottle()
@app.route('/')
def show_form():
return template('form.tpl')
@app.route('/submit', method='POST')
def submit_form():
user_name = request.forms.get('user_name') # ユーザー名を取得
age = request.forms.get('age') # 年齢を取得
return template('result.tpl', user_name=user_name, age=age)
run(app, host='localhost', port=8080)
この例では、/submit
エンドポイントでPOSTリクエストを受け取り、request.forms.get()
を使用してフォームデータを取得しています。
フォームデータをテンプレートに渡す方法
受け取ったフォームデータをテンプレートに渡すことで、ユーザーに入力内容を表示することができます。
以下は、結果を表示するためのテンプレートの例です。
<!-- result.tpl -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>結果</title>
</head>
<body>
<h1>入力された情報</h1>
<p>ユーザー名: {{ user_name }}</p>
<p>年齢: {{ age }}歳</p>
</body>
</html>
このテンプレートでは、user_name
とage
の変数を使用して、ユーザーが入力した情報を表示しています。
submit_form関数
で取得したデータをtemplate()関数
を通じて渡すことで、動的に内容が生成されます。
このように、Bottleを使用してフォームを作成し、データを受け取り、テンプレートに渡すことで、ユーザーとのインタラクションを実現できます。
静的ファイルとテンプレートの連携
静的ファイルの提供方法
Bottleでは、静的ファイル(CSS、JavaScript、画像など)を提供するために、static_file()関数
を使用します。
静的ファイルを格納するディレクトリを指定し、特定のURLパスにマッピングすることで、ブラウザからアクセスできるようにします。
以下は、静的ファイルを提供するための基本的な設定の例です。
from bottle import Bottle, run, static_file, template
app = Bottle()
# 静的ファイルを格納するディレクトリ
@app.route('/static/<filepath:path>')
def server_static(filepath):
return static_file(filepath, root='./static')
@app.route('/')
def index():
return template('index.tpl')
run(app, host='localhost', port=8080)
この例では、/static/<filepath:path>
というルートを定義し、static_file()関数
を使用して./static
ディレクトリ内のファイルを提供しています。
テンプレートでの静的ファイルの参照
静的ファイルをテンプレート内で参照するには、提供したURLパスを使用します。
以下は、CSSファイルをテンプレートに組み込む例です。
<!-- index.tpl -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>静的ファイルの例</title>
<link rel="stylesheet" href="/static/style.css"> <!-- CSSファイルの参照 -->
</head>
<body>
<h1>静的ファイルとテンプレートの連携</h1>
<p>このページはBottleを使用して作成されています。</p>
</body>
</html>
この例では、<link>
タグを使用して、/static/style.css
というパスでCSSファイルを参照しています。
これにより、スタイルが適用されます。
CSSやJavaScriptの組み込み
静的ファイルにはCSSだけでなく、JavaScriptファイルも含めることができます。
以下は、JavaScriptファイルをテンプレートに組み込む例です。
<!-- index.tpl -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>静的ファイルの例</title>
<link rel="stylesheet" href="/static/style.css"> <!-- CSSファイルの参照 -->
</head>
<body>
<h1>静的ファイルとテンプレートの連携</h1>
<p>このページはBottleを使用して作成されています。</p>
<button id="myButton">クリックしてメッセージを表示</button>
<script src="/static/script.js"></script> <!-- JavaScriptファイルの参照 -->
</body>
</html>
この例では、<script>
タグを使用して、/static/script.js
というパスでJavaScriptファイルを参照しています。
これにより、ボタンをクリックしたときにメッセージを表示する機能を追加できます。
// script.js
document.getElementById('myButton').addEventListener('click', function() {
alert('ボタンがクリックされました!');
});
このように、Bottleを使用して静的ファイルを提供し、テンプレート内で参照することで、スタイルやインタラクティブな機能を持つWebページを簡単に作成できます。
Bottleテンプレートのデバッグと最適化
テンプレートのデバッグ方法
Bottleでテンプレートをデバッグする際は、エラーメッセージやログを活用することが重要です。
テンプレート内でのエラーは、通常、ブラウザに表示されるエラーページに記録されます。
以下は、デバッグを行うための基本的な方法です。
- エラーメッセージの確認: テンプレート内でエラーが発生した場合、Bottleはエラーメッセージを表示します。
これにより、どの行でエラーが発生したかを特定できます。
debug
モードの有効化: Bottleをデバッグモードで実行することで、詳細なエラーメッセージを得ることができます。
以下のように、run()関数
にdebug=True
を指定します。
run(app, host='localhost', port=8080, debug=True)
- ログの出力: Bottleのロギング機能を使用して、エラーや警告をログファイルに記録することもできます。
これにより、後から問題を分析することが可能です。
テンプレートのキャッシュ機能
Bottleでは、テンプレートのキャッシュ機能を利用することで、パフォーマンスを向上させることができます。
キャッシュを有効にすると、同じテンプレートが再度レンダリングされる際に、以前の結果を再利用することができます。
これにより、処理時間を短縮できます。
キャッシュを有効にするには、以下のように設定します。
from bottle import Bottle, run, template
app = Bottle()
# キャッシュを有効にする
app.template_lookup.cache = True
@app.route('/')
def index():
return template('example.tpl')
run(app, host='localhost', port=8080)
この設定により、テンプレートが変更されない限り、キャッシュされた結果が使用されます。
ただし、開発中はキャッシュを無効にしておくことをお勧めします。
パフォーマンス向上のためのベストプラクティス
Bottleでのテンプレートのパフォーマンスを向上させるためのベストプラクティスは以下の通りです。
ベストプラクティス | 説明 |
---|---|
テンプレートの最適化 | 不要な計算や処理をテンプレート内で行わない。データは事前に準備しておく。 |
静的ファイルの圧縮 | CSSやJavaScriptファイルを圧縮して、読み込み時間を短縮する。 |
キャッシュの利用 | テンプレートのキャッシュ機能を活用し、再利用可能な部分をキャッシュする。 |
不要なリクエストの削減 | 必要なデータのみをリクエストし、無駄なデータの送受信を避ける。 |
CDNの利用 | 静的ファイルをCDN(コンテンツ配信ネットワーク)でホスティングし、読み込み速度を向上させる。 |
これらのベストプラクティスを実践することで、Bottleアプリケーションのパフォーマンスを向上させ、ユーザーに快適な体験を提供することができます。
Bottleテンプレートの応用例
複数ページのWebアプリケーションの作成
Bottleを使用して複数ページのWebアプリケーションを作成することは非常に簡単です。
各ページに対して異なるルートを定義し、それぞれのページに対応するテンプレートを用意します。
以下は、ホームページとアバウトページを持つシンプルなアプリケーションの例です。
from bottle import Bottle, run, template
app = Bottle()
@app.route('/')
def home():
return template('home.tpl')
@app.route('/about')
def about():
return template('about.tpl')
run(app, host='localhost', port=8080)
この例では、home.tpl
とabout.tpl
という2つのテンプレートを用意し、それぞれのルートに対応させています。
テンプレートファイルは以下のようになります。
<!-- home.tpl -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ホームページ</title>
</head>
<body>
<h1>ホームページ</h1>
<p>ようこそ!</p>
<a href="/about">アバウトページへ</a>
</body>
</html>
<!-- about.tpl -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>アバウトページ</title>
</head>
<body>
<h1>アバウトページ</h1>
<p>このアプリケーションはBottleを使用して作成されています。</p>
<a href="/">ホームページへ</a>
</body>
</html>
テンプレートを使ったAPIレスポンスの生成
Bottleでは、テンプレートを使用してAPIレスポンスを生成することも可能です。
JSON形式のレスポンスを生成する際に、テンプレートを利用して動的なデータを埋め込むことができます。
以下は、ユーザー情報をJSON形式で返すAPIの例です。
from bottle import Bottle, run, template, response
app = Bottle()
@app.route('/api/user/<user_id>')
def get_user(user_id):
# ユーザー情報のサンプルデータ
user_data = {
'1': {'name': '太郎', 'age': 25},
'2': {'name': '花子', 'age': 30}
}
user = user_data.get(user_id, {'name': '不明', 'age': 0})
response.content_type = 'application/json'
return template('user.tpl', user=user)
run(app, host='localhost', port=8080)
テンプレートファイルuser.tpl
は以下のようになります。
{
"name": "{{ user.name }}",
"age": {{ user.age }}
}
このようにすることで、指定されたユーザーIDに基づいて動的にJSONレスポンスを生成できます。
テンプレートを使ったメール送信機能の実装
Bottleを使用して、テンプレートを使ったメール送信機能を実装することも可能です。
メールの本文をテンプレートで生成し、SMTPを使用して送信します。
以下は、メール送信の基本的な例です。
from bottle import Bottle, run, template
import smtplib
from email.mime.text import MIMEText
app = Bottle()
@app.route('/send_email/<recipient>')
def send_email(recipient):
subject = "こんにちは!"
body = template('email_template.tpl', name=recipient)
msg = MIMEText(body)
msg['Subject'] = subject
msg['From'] = 'your_email@example.com'
msg['To'] = recipient
# SMTPサーバーの設定
with smtplib.SMTP('smtp.example.com', 587) as server:
server.starttls()
server.login('your_email@example.com', 'your_password')
server.send_message(msg)
return "メールを送信しました!"
run(app, host='localhost', port=8080)
メールテンプレートemail_template.tpl
は以下のようになります。
こんにちは、{{ name }}さん!
このメールはBottleを使用して送信されています。
このように、Bottleを使用してテンプレートを活用したメール送信機能を実装することで、動的なコンテンツを含むメールを簡単に送信できます。
まとめ
この記事では、Bottleフレームワークを使用してテンプレートを活用する方法について詳しく解説しました。
具体的には、テンプレートの基本的な使い方から、データの渡し方、静的ファイルとの連携、さらには応用例として複数ページのWebアプリケーションやAPIレスポンスの生成、メール送信機能の実装まで幅広く取り上げました。
これらの知識を活用することで、より効果的なWebアプリケーションを構築することが可能になりますので、ぜひ実際に手を動かして試してみてください。