全てのHTMLリクエストをPythonで処理してから出力する
【宣伝】下記のページでも利用している技術です。
共円(http://my-android-server.appspot.com/)
twitter連携などを行うと、ログイン状態や情報の取得など、全てのページで必要な処理が出てきました。
そのため、全てのHTMLリクエストをpythonのモジュールを通して処理するようにしてみました。
html.py
#!/usr/local/bin/python # -*- coding: utf-8 -*- import os import logging import math import Cookie import tweepy import uuid from google.appengine.ext import webapp, db from google.appengine.api import memcache from google.appengine.ext.webapp import template from google.appengine.ext.webapp.util import run_wsgi_app def render_page(handler, page, values=None): template_values = values or {} # ここに常に行う処理を記述する(ログイン情報を'template_values'に詰めるとか) path = os.path.join(os.path.dirname(__file__), 'template', page) html = template.render(path, template_values) handler.response.out.write(html) class StaticPage(webapp.RequestHandler): def get(self, value=None): if not value: value = 'index.html' render_page(self, value) def post(self): self.get(self) application = webapp.WSGIApplication([('/', StaticPage), ('/page/(.*)', StaticPage), ], debug=True) def main(): run_wsgi_app(application) if __name__ == "__main__": main()
(import周りは精査するのがめんどくさくて、そのままですが・・・)
それ以外の部分は以前の記事とほぼ同じです。
GAE/Pythonで、テンプレートを利用したHTMLの表示 - 混沌とした備忘録
これにより、welcome pageとして、'template/index.html'が表示され、
それ以外の'/page/hogehoge.html'へのリクエストは、共通処理を行ったあとに、
'template/hogehoge.html'の内容が表示されます。
webapp.WSGIApplicationの引数に、'(.*)'のように記述すると、
get関数の、selfの次の引数(第一引数と言うの?)として渡されるようです。
その変数を'render_page'という自作の関数に渡し、その中で共通処理を実行します。
結果を'template_values'に入れたりして、引数で指定されたページをrenderに渡しています。
特別な処理が必要なページに対しては、
class HogePage(webapp.RequestHandler): def get(self): # 特別な処理 render_page(self, 'hoge.html', template_values) def post(self): self.get(self) application = webapp.WSGIApplication([('/', StaticPage), ('/page/hoge.html', HogePage), ('/page/(.*)', StaticPage), ], debug=True)
のように、'/page/(.*)'より前に記述したら、そちらが優先されます。
ログイン処理などの非機能要件(?)は、本来はロジックと分離すべきかとは思います。
ただ、Javaで言う、「javax.servlet.Filter継承のクラスをweb.xmlに登録」みたいな機能がGAE+Pythonで見つかりませんでした。
知ってる人がいたら、教えてください。
書いてる途中で気がつきましたが、継承とか使えば、もうちょっと綺麗に書けるかも・・・