箱が…

Amazon箱ストラクチャーが崩れてきそうです。ダンボー作ろうかな。

GAE Oilのテンプレートに渡される変数について


始めてからずいぶん放置してるこのblogですが、たまには何か書こうかということでGoogle App Engine(GAE)のうすーいラッパーフレームワークであるところのGoogle App Engine Oil(GAEO)のお話


内容としてはGAEとGAEOのテンプレートの使い方の差、というか実際GAEOの中身はどうなってんの?っていうところを簡単に解説のようなことをしたいと思います。


メモ的な意味が7割、ついでに公開するかという気持ちが2割、blog放置してたから丁度いいやという思いつきが1割でお送りします。


なおGAEOのバージョンは0.3です。

webapp+Django


さて、GAEには標準のフレームワークとしてwebappっていうのがビルトインされてるんだけど、そのテンプレートシステムにDjangoのそれが使われてるわけですよ。


そしてGAEOのテンプレートシステムもwebappをほとんどそのまま引っ張ってきてるおかげで引き続きDjangoのが使える。


webappのテンプレートシステムを使うときは以下のように記述します

from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
class HogeHandler(webapp.RequestHandler):
  def get(self):
    # 中略
    processed_template = template.render(path_to_templete, template_values)
    self.response.out.write(processed_template)


これはまあ普通のwebappの使い方。

ここで覚えておいてほしいのはtemplate.render()っていうメソッドでテンプレート内の変数を置換したり色々と処理をしてるっていうこと。

GAEO


さて次にGAEOの(MVC的な意味での)Controllerを使って出力しますよ。

なぜControllerなのかと言われればgaeogen.pyというユーティリティスクリプトでscaffoldしたら出てきたコードがそうだったからだ!


なおHogeという名前のデータストアモデルが既に定義されているものとします。そこのとこよろしく。

from gaeo.controller import BaseController
from model.hoge import Hoge
class HogeController(BaseController):
  def index(self):
    query = Hoge.all()
    self.result = query.fetch(limit=1000)

GAEOの中を探検


さて、これを見て俺は思った。

self.resultとはなんぞや」と


取ってきたデータはself.resultという変数に突っ込まないといけないのか、別にself.resultじゃなくてもいいのか。

まあ結論から言うと後者なんだが。

呼び出し元発見


で、ちょっとGAEOの中を探し回った結果PROJECT ROOT/gaeo/dispatch/dispatcher.pyの166行目あたりでBaseControllerのrenderメソッドを呼んでるのが判った。

なおctrlはControllerのインスタンス

if not ctrl.has_rendered:
  ctrl.render(template=route['action'],
              values=ctrl.__dict__)
Google App Engine Oil gaeo/dispatch/dispatcher.py
呼ばれた方とtemplate.render()発見


で、このrenderメソッドはPROJECT ROOT/gaeo/controller/__init__.pyの217行目あたりでお馴染みwebappのtemplate.render()を呼び出している。

def render(self, *html, **opt):
  # 大幅に略
  content = template.render(os.path.join(self.__tpldir,
          opt.get('template') + '.html'), context)
Google App Engine Oil gaeo/controller/__init__.py


で、テンプレートに突っ込むデータが入ってるはずのcontextっていう変数は188行目あたりで

context = self.__dict__
if isinstance(opt.get('values'), dict):
  context.update(opt.get('values'))
Google App Engine Oil gaeo/controller/__init__.py
探検結果


というわけで、結果的にControllerの__dict__

つまりオブジェクトの(書き込み可能な)属性が全部テンプレートに渡されるということで、結局はself.resultどころか変数名は何でもいいということのようです。


以上メモでした