今回はテンプレートを使用してHTMLやCSSなどのデザイン部分を外部化する方法と静的ファイルの扱い方を説明する。
GAE for Python は有名所のPython用テンプレートシステム(例えば、EZT、Cheetah、ClearSilver、Quixote、Django 等)が、ほぼどれでも使える。とは言え、webapp フレームワークにはデフォルトで Django のテンプレートエンジンが用意されているのでそれを使うのが手っ取り早い。
というわけで、早速その使い方を説明する。
■HTMLを外部化
まずは、いつもの helloworld.py を以下のソースコードに書き換えて見てよう。
# -*- coding: utf-8 -*-
import cgi
import os
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
from google.appengine.ext import db
class Greeting(db.Model):
author = db.UserProperty()
content = db.StringProperty(multiline=True)
date = db.DateTimeProperty(auto_now_add=True)
class MainPage(webapp.RequestHandler):
def get(self):
greetings_query = Greeting.all().order('-date')
greetings = greetings_query.fetch(10)
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
else:
url = users.create_login_url(self.request.uri)
url_linktext = 'Login'
template_values = {
'greetings': greetings,
'url': url,
'url_linktext': url_linktext,
}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))
class Guestbook(webapp.RequestHandler):
def post(self):
greeting = Greeting()
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get('content')
greeting.put()
self.redirect('/')
application = webapp.WSGIApplication(
[('/', MainPage),
('/sign', Guestbook)],
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
次に、helloworld フォルダに新規で index.html というファイルを作り、以下のようにDjangoテンプレートの作法に則って編集する。詳細についてはDjango組み込みタグ・フィルタリファレンスをチェックすべし。
<html>
<body>
{% for greeting in greetings %}
{% if greeting.author %}
<b>{{ greeting.author.nickname }}</b> wrote:
{% else %}
An anonymous person wrote:
{% endif %}
<blockquote>{{ greeting.content|escape }}</blockquote>
{% endfor %}
<form action="/sign" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
<a href="{{ url }}">{{ url_linktext }}</a>
</body>
</html>
さて、ここまでできたら開発用サーバを起動し、 http://localhost:8080 へアクセスしてみよう。
アプリ画面の一番下に Login というリンクが作られた筈だ。
このリンクをクリックするとダミーのログイン画面が出現するので、そこで適当なメールアドレスを入力するとダミーログイン状態になる。そして、メイン画面でメッセージを投稿するたびに自分のメアドも登録&表示されるようになる。
では上のソースコードから重要な箇所を抜き出して説明してみよう。
まず、テンプレートエンジンを利用するために以下のように関連モジュールを読み込んでいる。
import os
from google.appengine.ext.webapp import template
そして以下のようにしてテンプレートエンジンを扱う。
template_values = {
'greetings': greetings,
'url': url,
'url_linktext': url_linktext,
}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))直感的に分かる人もいるだろうが一応説明しておくと、template_values = {...} という箇所でテンプレート(index.html)で使用されているキー( {{ hoge }} のように記述されている部分)とそこへ格納する値を紐付けており、path = os.path.join(os.path.dirname(__file__), 'index.html')で index.html の絶対パスを取得し、最後に template.render(path, template_values) で index.html へテンプレートを適用&レンダリングされたHTMLテキストを返している。
なお、テンプレートを共通化してメンテナンス性を更に高めたい場合はこちらを参照のこと。
■CSSや画像も外部化
次は、スタイルシートや画像などの静的ファイルを扱えるようにしてみよう。
まず、app.yamlを以下のように書き換える。
application: helloworld
version: 1
runtime: python
api_version: 1
handlers:
- url: /stylesheets
static_dir: stylesheets
- url: /.*
script: helloworld.py
そして、helloworld/stylesheets フォルダを作成して、そこへ main.css というファイルを作成し、以下のように書く。
body {
font-family: Verdana, Helvetica, sans-serif;
background-color: #DDDDDD;
}次に先程の index.html にこのスタイルシートを読み込ませるために<html>直下に以下のような記述を追加する。
<head>
<link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />
</head>
これでページをリロードしてみればスタイルシートが適用されている筈だ。
app.yaml に追加された、
- url: /stylesheets
static_dir: stylesheets
という部分は、/stylesheetsというURLへのアクセスがstylesheetsというフォルダ配下にある静的ファイルへのアクセスであることを表している。
画像の静的ファイルを使いたい場合も上と同様に、app.yamlのhandlers:の下へ
- url: /images
static_dir: images
を追加し、helloworld/imagesフォルダを作り、そこへ適当な画像ファイル(例えば hoge.jpg)を保管すれば、index.html内で以下のようにして画像が扱えるようになる。
<img src="/images/hoge.jpg" />
要するにCSSだろうが画像だろうが、静的ファイルを扱いたい場合は app.yaml を弄って明示的にファイルの場所を指定すればいいということだ。
GAE for Pythonにおけるデザインの外部ファイル化は以上である。
次回はGAEアプリのアップロードを説明する。いよいよあなたのアプリが世界へお披露目されるというわけだ。
(続く)
【GAE for Pythonの最新記事】
- GAE/Pでmemcacheを利用してデ..
- PythonでJST日付をUTC(GMT..
- BeautifulSoupオブジェクトを..
- GAE/Pで詳細なエラーログ(トレース情..
- Pythonでオブジェクトのlistをソ..
- GAE/PでAspyctを使ってAOP(..
- GAE/Pでカスタムタグを作って日付をU..
- GAE/PでBeautifulSoupを..
- GAE/Pでログインが必要なページを取得..
- GAE/Pでファイルアップロード。
- GAE/Pでリクエストデータの扱い方。
- GAE/PでCRONを使ったスケジュール..
- GAE/PでModelをJSON変換する..
- GAE/P向け統合開発環境 Eclips..
- GAE/PとjQueryでJSONデータ..
- GAE+Pythonの標準モジュールだけ..
- GAE+Pythonでテンプレートの共通..
- GAEアプリをアップロードする方法。
- GAE+Pythonでデータストアを操作..
- webappフレームワークを使ったフォー..