
さいきんすっかり放置です、すみません。参考程度にお願いします。2009/8 冨田
MobileCat のモバイルサイト的機能から見たソース逆引きと使ってるモジュールの簡単な説明です。MobileCat とは もご覧下さい。
携帯/PCでページを切り分け
HTTP::MobileAgent を Catalyst::Plugin::MobileAgent 経由で利用。TT の WRAPPER を2段にして、上の WRAPPER でモバイル用の WRAPPER と PC 用の WRAPPER を切り分けてます。
IP制限をする
Net::CIDR::MobileJP を利用。帯域情報を新たに作り sharedir に置いておく場合は、同梱のスクレイパーを使いつつ以下のように入れるとすると良さげ。この場合帯域情報 YAML は make install で /usr/lib/perl5/site_perl/*/auto/Net/CIDR/MobileJP/cidr.yaml とかに置かれますが、IP は更新されるものなのでメンテ必須です。
# cpan
cpan> look Net::CIDR::MobileJP
# perl net-cidr-mobilejp-scraper.pl > share/cidr.yaml
# perl Makefile.PL
# make
# make test
# make install
# exit
絵文字をマッピングした Unicode を使う
Catalyst::Controller::Mobile::JP を Controller/Root.pm のベースコントローラとして使っています。
これにより最初の Root::begin() で $c->request->params は UserAgent の値を元に自動で Encode::JP::Mobile の中のよさげなエンコーディングで Encode::decode() され、以後 Unicode として扱えます。最後の Root::end() で $c->response->body に対して逆のことが行なわれ、よさげなエンコーディングで Encode::encode() されて出ていきます。
MobileCat では Root::end() でやりたいことがあったので end() を実装したので、Catalyst::Controller::Mobile::JP の end() も呼ばれるよう $c->next::method で回しています。
DB へは DBIx::Class::UTF8Columns を使って utf-8 で普通に encode() して保存・decode()してるだけです。
絵文字の相互変換
というわけで Unicode を encode() する際に、UserAgent が携帯の場合はそのキャリアにあった Encode::JP::Mobile のエンコーディングで出力されますが、これはキャリア間でメール送信する際の相互変換をエミュレートしているので、キャリア間の相互変換ができています。
PC 向けに絵文字を出す
HTML::MobileJp::Filter を Catalyst::View::MobileJpFilter 経由で利用しています。
HTML::MobileJp::Filter は UserAgent と HTML を渡すと何かをするというものをプラグインで使える薄いフレームワークです。今回 PC 向けに絵文字を出すために使っているのは HTML::MobileJp::Filter::PictogramFallback::TypeCast と HTML::MobileJp::Filter::PictogramFallback です。
これにより、Typecast Mobile がフリーで公開してくれている絵文字の範囲(DoCoMo に同じ)はそれを出し、それ以外は Encode::JP::Mobile::Character の fallback_name(DoCoMo にない絵文字を DoCoMo に送った場合になる文字)を出すようにしています。
CSS をインライン展開
xhtml が使えない機種は無視しているので、キャリアごとに気をつけないといけない点はだいぶ少ないですが、DoCoMo に合わせて CSS をインライン記述するのはたいへんなので HTML::MobileJp::Filter::DoCoMoCSS 経由で HTML::DoCoMoCSS を使い外部 CSS の内容を style= タグに自動変換しています。
なお現時点で HTML::DoCoMoCSS が内部で利用している CSS::Tiny::Style の制限で、アンダースコアやハイフンを含んだクラス名が使えません。あと :visited などの擬似クラスも使えません。まあそのうちなんとかなるでしょう。
メールアドレスからキャリアを知る
Email::Address::JP::Mobile でやっています。これは近日 CPAN に UP 予定。
モバイルのアドレスかどうか
FormValidator::Simple::Plugin::Japanese 経由で Mail::Address::MobileJp を使い携帯のアドレスだけ通したりしています。
絵文字を含んだメールを送信する
Email::Address::JP::Mobile と Encode::JP::Mobile の MIME エンコーディング(両方ともまだ CPAN にはない)を使い、こちらで紹介されている方法で送信しています。メールのテンプレートはこちら。
絵文字を含んだメールから絵文字を生かしてデータを取る
といっても gmail.com ドメインではないので au 以外からは取れないですが。Email::Address::JP::Mobile でもう少し簡単にできるようにしようと思いますがとりあえずこの方法で取っています。au からであれば絵文字が生きます。
昨今セキュリティの専門家からも問題提起がなされていますが、是非はともかく DoCoMo 端末で Cookie が使えるようになるまでは使わざるを得ない場合もあると思うため使っています。推し進めようというわけではないので誤解なきよう。
端末IDを取得する
HTTP::MobileAgent の user_id() で取れます。DoCoMo は guid=ON クエリが必要なので、ドコモの場合 HTML::MobileJp::Filter::DoCoMoGUID 経由で HTML::StickyQuery::DoCoMoGUID を使い guid=ON を自動でつけまくりです。
Catalyst の場合 $c->uri_for を使うことも多いと思いますが、絶対パスの場合 HTML::StickyQuery::DoCoMoGUID は外部サイトとして guid=ON しません。なのでテンプレートの場合では Catalyst::Plugin::SmartURI の hostless になるようにしています。
端末IDを認証に使う
Catalyst::Authentication::Credential::MobileID 的なものを作ろうかと思いましたが、Catalyst::Plugin::Authentication フレームワークは、ログインできた・できないのみであり、その理由を保存する場合 stash に入れるとか変なことが必要なため、ベースコントローラでやっています。内容は簡単で、UA・IP・ID を順にチェックしています。
位置情報や画像サイズ、HTML の分断とかトルカみたいなマニアックなものまでモバイル向けのモジュールは他にもいろいろあります。気が向いたら無理やり MobileCat に組み込んでみようと思います。