「bottle」+「jinja2」を使ってサイト構築 1
最近は一時期よりは下火になっているものの、PythonでフレームワークといえばDjango。
でもさくっとページを作りたいときにはちょっとがっちりしすぎていて作りづらい。
ということで、最近は bottle を使っている。
ただ、bottle標準のテンプレートエンジンが使い慣れないため、テンプレートエンジンは
Djangoで使われているテンプレートエンジンエンジン jinja2 を使っている。
サンプルコードはこちら
(次回以降に紹介したコードも含む)
bottle、jinja2をインストール
virtualenv で切ってbottleをインストールする。
[shell]
$ mkdir python_bottle
$ cd python_bottle
$ virtualenv-3.4 python
$ source python/bin/activate
(python)$ pip install bottle jinja2
[/shell]
使い方の確認
以降の説明では、どこからがbottleの機能、もしくはjinja2の機能といった紹介をせず
に説明していく。
ソースファイルを設置するsourceディレクトリを作成する。
また、sourceディレクトリ内にテンプレートファイルを設置するviewsディレクトリと、
スタティックなファイルを設置するstaticディレクトリを作成する。
更に、staticディレクトリ内にjs、css、imgディレクトリを作成する。
[shell]
(python)$ mkdir -p source/{views,static}
(python)$ mkdir -p source/static/{js,css,img}
[/shell]
以下のソースファイル index.py と views内にトップページのテンプレートファイル top.html
を作成する。
[python title="source/index.py"]
# -*- coding: utf-8 -*-
import os
from bottle import route, run
from bottle import TEMPLATE_PATH, jinja2_template as template
# index.pyが設置されているディレクトリの絶対パスを取得
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# テンプレートファイルを設置するディレクトリのパスを指定
TEMPLATE_PATH.append(BASE_DIR + "/views")
# 今回の場合は https://localhost:8080/top にアクセスが来た場合に公開する内容を指定。
# route関数をデコレータとして呼び出し、route関数の引数で/以降のアクセス先を指定する。
@route('/top’)
def top():
return template('top’)
if __name__ == "__main__":
# localhost:8080 で公開するように実行
run(host="localhost", port=8080, debug=True, reloader=True)
[/python]
[html title="source/views/top.html"]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>テストページ</title>
</head>
<body>
テストページ
</body>
</html>
[/html]
記述後、index.pyを実行する。
[shell]
(python)$ python source/index.py
[/shell]
実行後、ブラウザで https://localhost:8080/top にアクセスすると以下のように表示される。
テンプレートへの変数の渡し方
テンプレートへの変数の渡し方は template関数で行う。
[python]
template(テンプレートファイル名, テンプレート内での変数名1=渡す変数1, テンプレート内で使う変数名2=渡す変数2, …)
[/python]
上で作った index.py と top.html で試す。
[python title="index.py"]
# -*- coding: utf-8 -*-
from bottle import route, run
from bottle import TEMPLATE_PATH, jinja2_template as template
# index.pyが設置されているディレクトリの絶対パスを取得
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# テンプレートファイルを設置するディレクトリのパスを指定
TEMPLATE_PATH.append(BASE_DIR + "/views")
@route('/top’)
def top():
# 配列を渡すための準備
fizzbuzz = []
for i in range(1, 100):
if i % 3 == 0 and i % 5 == 0:
fizzbuzz.append(str(i) + ": fizzbuzz")
elif i % 3 == 0:
fizzbuzz.append(str(i) + ": fizz")
elif i % 5 == 0:
fizzbuzz.append(str(i) + ": buzz")
else:
fizzbuzz.append(str(i))
return template('top’, name="umentu", fizzbuzz=fizzbuzz)
if __name__ == "__main__":
run(host="localhost", port=8080, debug=True, reloader=True)
[/python]
[html title="top.html"]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>テストページ</title>
</head>
<body>
<!–変数を使う場合は、{{}} の中に変数名を記述–>
こんにちは、 {{name}}
<h1>今日のfizzbuzz</h1>
<!–
配列fizzbuzzから1つずつ順番にデータを取り出し、fzbzに代入。
fzbzは単なる変数のため、{{}}で表示
–>
{% for fzbz in fizzbuzz %}
{{ fzbz }}<br />
{% endfor %}
</body>
</html>
[/html]
index.pyを実行したままなら再読込されているはず。
index.pyを停止した場合は再度実行してブラウザでアクセスすると、以下のように表示される。
動的なルーティングの指定
何かというと、https://localhost:8080/top/’username’ を来るように仕向けた場合、
'username’の部分の値を取得して利用する方法のこと。
index.py、top.htmlを次のように書き換える。
[python title="index.py"]
# -*- coding: utf-8 -*-
import os
from bottle import route, run
from bottle import TEMPLATE_PATH, jinja2_template as template
from bottle import static_file
# index.pyが設置されているディレクトリの絶対パスを取得
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# テンプレートファイルを設置するディレクトリのパスを指定
TEMPLATE_PATH.append(BASE_DIR + "/views")
"""
routeは複数指定できる。
上の場合は/top/のあとに何も指定せずにアクセスが来た場合。
下の場合は、/top/の後にユーザー名を指定したアクセスが来た場合。
ルーティングで値を渡す部分に関しては<>で括る。
"""
"""
<>でくくった名前を関数の引数名で渡す。
username="anonymous" としているのは、@routeの上の場合の
ユーザー名の指定がなかった場合にanonymousとして利用するため。
"""
@route('/top/’)
@route('/top/<username>’)
def top(username="anonymous"):
# 配列を渡すための準備
fizzbuzz = []
for i in range(1, 100):
if i % 3 == 0 and i % 5 == 0:
fizzbuzz.append(str(i) + ": fizzbuzz")
elif i % 3 == 0:
fizzbuzz.append(str(i) + ": fizz")
elif i % 5 == 0:
fizzbuzz.append(str(i) + ": buzz")
else:
fizzbuzz.append(str(i))
# name に username の値を渡す。
return template('top’,name=username, fizzbuzz=fizzbuzz)
if __name__ == "__main__":
run(host="localhost", port=8080, debug=True, reloader=True)
[/python]
[html title="top.html"]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>テストページ</title>
</head>
<body>
<!–変数を使う場合は、{{}}の中に変数名を記述–>
こんにちは、 {{name}}
<h1>今日のfizzbuzz</h1>
<!–
配列fizzbuzzから1つずつ順番にデータを取り出し、fzbzに代入。
fzbzは単なる変数のため、{{}}で表示
–>
{% for fzbz in fizzbuzz %}
{{ fzbz }}<br />
{% endfor %}
</body>
</html>
[/html]
ブラウザでアクセスすると以下のようになる。
Djangoに比べると、導入はかなり楽に感じられる。
次回はbootstrapを読み込んだりjQuery使ったりといったstaticな部分から。
ディスカッション
ピンバック & トラックバック一覧
[…] サンプルコードはこちら (他の回に紹介したコードも含む) フレームワークを利用して一括してフォームを作成したいときなどに便利。 (以降の手順はbottle+jinja2の紹介内容を踏まえている。それらの使い方に関しては割愛。) […]