前回に続きPythonの軽量WebフレームワークBottleのソースを読む テンプレート編
Bottleのテンプレートについて
Bottleのテンプレートは、Simple、Cheetah、Jinja2、Makoの4種類があり、BaseTemplateを継承しているPythonのテンプレートの種類
テンプレートの使い方
テンプレートの拡張子には以下が利用できる
extensions = ['tpl', 'html', 'thtml', 'stpl']
例えばjinja2を使う場合は以下のように呼び出すことができる(jinja2をpip installする必要あり)
@route('/')
def jinja2():
name = 'text'
return jinja2_template('jinja2', name=name)
view
{{ name }}
テンプレート呼び出しの処理をみてみる
各テンプレートは以下のように設定されている。 functools.partialにfunc templateが渡されている
mako_template = functools.partial(template, template_adapter=MakoTemplate)
cheetah_template = functools.partial(template, template_adapter=CheetahTemplate)
jinja2_template = functools.partial(template, template_adapter=Jinja2Template)
jinja2_templateが呼ばれた時の処理
- argsにはjinja2が、**kwargsにはtemplate_adapter=Jinja2Templateが渡される
def template(*args, **kwargs):
引数からjinja2テンプレート名を取得
tpl = args[0] if args else None
Jinja2Templateを取得
adapter = kwargs.pop('template_adapter', SimpleTemplate)
テンプレートパスをlookup(パスは./views/か./)
lookup = kwargs.pop('template_lookup', TEMPLATE_PATH)
Jinja2Templateをインスタンス化
TEMPLATES[tplid] = adapter(name=tpl, lookup=lookup, **settings)
BaseTemplateのコンストラクタの最後のprepareでJinja2Templateのprepareが呼ばれる
self.prepare(**self.settings)
ここではじめてjinja2がimportされる
from jinja2 import Environment, FunctionLoader
テンプレートのrenderメソッドにてレンダリングしviewを返す
return TEMPLATES[tplid].render(kwargs)
BottleのテンプレートはBaseTemplateを継承しprepareとrenderを実装することで使える仕組みになっている
def prepare(self, **options):
""" Run preparations (parsing, caching, ...).
It should be possible to call this again to refresh a template or to
update settings.
"""
raise NotImplementedError
def render(self, *args, **kwargs):
""" Render the template with the specified local variables and return
a single byte or unicode string. If it is a byte string, the encoding
must match self.encoding. This method must be thread-safe!
Local variables may be provided in dictionaries (args)
or directly, as keywords (kwargs).
"""
raise NotImplementedError