PhoneGap(Cordova)アプリで jQuery Mobile で複数画面遷移する HTML ファイルを生成する
HTML ファイルをどう扱うか考えていた
というのが以前の記事 PhoneGap(Cordova) + jQuery Mobile でアプリを構築しようとして調べた雑多なこと - atas
ベタ書きで固定フッターやヘッダーを出力するのはさすがに面倒だし絶対ミスがおこる。一般的な Web フレームワークならテンプレートエンジンでどうこうできるし、サーバーなら SSI で include できる。しかし今回は PhoneGap アプリなので中身は HTML + CSS + JS になるからそれはできない。じゃあ $(selector).load(template) したらどうか?というのを昨日やっていたりしたのだけど、アイコンが二重に表示されるバグ(仕様?)があったり、結局スマホのアニメーションを jQuery Mobile で扱おうとするとこれはまたベタ書きで面倒なことになる。さて、どうしよう。やっぱり1枚の HTML にするしかないのか、しかし疎結合にしたいし、さて。
別にテンプレートエンジンで HTML 出力できた
結論としては Python を扱っているし普段 Django 使ってるので Jinja2 というテンプレートエンジンを採用することにした。Jinja2 自体は Flask のテンプレートエンジンとしてもお馴染み。Django のテンプレートエンジンが先か Jinja が先かはわからないけど、似たような感じでかけるのでとても楽です。
参考までにコード。まず base.html を定義してやる
<!DOCTYPE HTML> <html lang="ja"> <head> <meta charset="UTF-8"> <title>hoge</title> <link rel="stylesheet" href="hoge/css/jquery.mobile-1.2.0.min.css" /> <script type="text/javascript" src="cordova-2.2.0.js"></script> <script type="text/javascript" src="hoge/js/jquery-1.8.2.min.js"></script> <script type="text/javascript" src="hoge/js/jquery.mobile-1.2.0.min.js"></script> </head> {% block body %}{% endblock %} </html>
で、メインとなる index.html はこんな感じ
{% extends "base.html" %} {% block body %} <body> <div data-role="page"> {% include "header.html" %} <div data-role="content"> <ul data-role="listview" id="index"> <li class="ui-btn ui-btn-icon-right"> <div class="ui-btn-text"> <a href="#page2" data-transition="slide">page2</a> </div> </li> <li class="ui-btn ui-btn-icon-right"> <div class="ui-btn-text"> <a href="#moge" >moge</a> </div> </li> </ul> </div> <div id=debug></div> {% include "footer.html" %} </div> </body> {% endblock %}
base.html を継承していて、中身で include で部分的に入れてますね。例えばヘッダーは
<div data-role="header"> <h2>Hoge Project</h2> </div>
これだけ。でもヘッダーとかは共通で使われたりするし、やっぱりこうして部品化しておきたい。
最終的にはこれらのテンプレートファイルを1枚の index.html に組みなおしてやる必要がある。簡単な Python スクリプト main.py をかいた
# coding: utf-8 from jinja2 import Environment, FileSystemLoader args = [] kwargs = {} env = Environment(loader=FileSystemLoader('templates')) tmpl = env.get_template('index.html') html = tmpl.render(*args, **kwargs) print(html) with open("index.html", 'w') as f: f.write(html)
サーバーからどう値を受け取ったりなんなりはわからないから、とりあえず *args **kwargs しておいた。PackageLoader のサンプルが多いけど今回はそういうパッケージじゃないからまあ FileSystemLoader でいいかなと。で、print(html) で実際のペラ1枚になった HTML が出力されます。とりあえずてきとうにファイル書き込みにしておいた。
だいたいそんなところですかね。
補足::いろいろ Python のテンプレートエンジンを調べた & おしえてもらった
まあいろいろある。意見をもらったのも踏まえて箇条書きにする
- Jinja2
- とりあえず Django に慣れてるなら楽
- Mako
- Pyramid でつかわれたりするテンプレートエンジン
- 高機能で実行速度が早いらしい、が、Jinja2 もけっこうできがいいので無理に使う必要はないかもしれない
- PHP ではないが Pyhton コードを埋め込んだりできるし、そこらへんの拡張性がいいのかもしれない
- Cheetah
- ちょっと前(2007,8年?)にはわりと使われていたりしたらしいが、いまはメンテナンスされてないし選ぶ理由もなさそう
- hyde
- というのもあるようだ。日本語情報はないですね(別にそれ自体はいいけど、結局 Jinja2 が楽そうなのでいいや)
- from string import Template
- 標準モジュールの string でそもそも Template がある
- ざっと調べた限りたしかに簡単に出力できる。が、しかしまあ Jinja2 あるから使う必要もないかな
- Genshi
- XML ベースでどうとか。なんかデザイナーにわたすときには使いやすいかもしれないらしい
- mighty
- Cheetah と Mako の間にそういうプロジェクトがあったらしい
- ClearSilver
- Trac でつかわれてたとかどうとか?
- Chameleon
- XML ベースらしい
- Kajiki
- XML ベースらしい
- TurboGears 系らしい