[Symfony2]Mobile-Detectを拡張して端末別にビューファイルを切り替える

投稿者: | 2014/09/30

更新間隔がまた空いてしまいました。
最近異動が決まりまして10月から東京に転勤することになりましたので引越し準備に追われていました。

Webサイトを作成する際、エンジニアやデザイナーにとって考えなければならないのが端末別のデザインへの対応だと思います。
開発サービスやターゲット層によりますが、PC、タブレット、スマホ、場合によってはフィーチャーフォン(ガラケー)など多くの端末に対応する必要があります。最近ではBootstrap3のようなレスポンシブデザインだとPCやスマホにも対応が簡単にできるかもしれませんが、フィーチャーフォンのようにJavaScriptやCSSファイルを適用することが難しいこともありますので、多くの場合はUserAgentから端末判別して、端末別にビューファイル(HTMLなど)を作成してブラウザに表示させるか、サブドメイン(スマホならs.exaple.com, フィーチャーフォンならf.exaple.comなど)にリダイレクトさせることになるかと思います。

そこで今回は、Symfony2で端末ごとにビューファイル(twig)を切り替えることをしてみました。
端末を識別する仕組みが必要なので、Mobile-Detectを使ってみました。Mobile-DetectをSymfony2用に拡張したMobileDetectBundleもありますが、今回はビューファイルを切り替えるというシンプルな仕組みなのでこのバンドルは使いません。

今回の目標

  • Symfony2で端末別にビューファイル(twigテンプレート)を切り替えてブラウザに表示(レンダリング)する

環境

  • PHP 5.5.16
  • Symfony2 (2.3.16)
  • Mobile-Detect 2.8.4

前提条件

  • 以下の名前でバンドルを作成するとします
    • Shu1MobileDetectBundle
  • Symfony2の初期設定は完了して、正常にアプリケーションが動作しているとします

Mobile-Detectのインストール

Composerでインストールします。

Mobile-Detectを拡張したMobileDetectServiceを作成

Mobile-Detectをそのまま使っても良いのですが、後にFunctionalTestでUserAgentを設定してテストする場合、そのままでは動かなかったので拡張したサービスを作成します。

サービス登録する設定ファイルがデフォルトでXML(services.xml)になっているので、YAML(services.yml)に変更します。

services.ymlMobileDetectServiceを登録します。

MobileDetectServiceを作成します。

Symfony2の場合、HTTPヘッダをHTTP_のプレフィックスを削除して格納しており、そのままMobile-Detect::isMobile()では使えないため、HTTP_プレフィックスを付けたヘッダ内容に置き換えてMobile-Detect::isMobile()を呼び出しています。

Mobile-Detect::isMobile()の結果に応じてビューファイルを切り替えるイベントリスナーを作成

MobileDetectService::isMobile()を使って、ビューファイルを切り替える処理を行います。
通常なら、フロントコントローラか、各コントローラに処理を書くかもしれませんが、イベントリスナーという仕組みを使って、ビューファイルをレンダリングするタイミング(イベント)で切り替えるようにします。

services.ymlでイベントリスナーを登録します。
リスナー名は分かりやすくMobileDetectListenerという名前にします。

MobileDetectListenerを作成します。

モバイル端末の場合、ビューファイル(twigテンプレート)名がxxxx.mb.html.twigになり、それ以外はxxxx.html.twigとなります。
ガラケーとスマホを分けたい場合や、Android,iPhoneで分けたい場合など条件やテンプレートファイル名は適宜変更してください。

ビューファイルを作成します。テンプレートはtwigを使います。
モバイル版のテンプレートファイルを作成します。

モバイル以外(PC版)テンプレートファイルを作成します。

コントローラを作成します。

UserAgentを変更してブラウザからアクセスして、PC版とモバイル版で表示が切り替わっていればOKです。

テストコードを書く

先ほど少し書きましたが、FunctionalTestを行うことで、リクエストからレスポンスまでの総合的なテストを書くことができますので、ビューが切り替えることをテストします。

DefaultControllerTestを作成します。

モバイル版のUserAgentにiPhoneをテストに使ってみました。
アサーション内容がイマイチだし、テストケースが貧弱ですが、サンプルなのでご容赦ください。他のUserAgentを増やしてテストしたい場合は、DataProviderを使ってみてください。

PHPUnitを実行してテストが通れば完了です。

最後に

Symfony2でイベントリスナーを利用して、PC、スマホで別々のビューファイルをレンダリングしてみました。
これよりももっと柔軟に拡張したい場合は、冒頭に紹介したMobileDetectBundleを使ったほうが楽かもしれません。

しかし、特殊な事情があり、MobileDetectBundleで対応できない場合は、自前で今回紹介したような対応を取る必要があります。
最近仕事で、PC、スマホ、フィーチャーフォン別にビューファイルを切り替えなければならない場合があり、しかもフィーチャーフォンの場合は、各携帯キャリアが公開しているIPアドレス帯域(後述)からアクセスしているかで端末判別する必要があったので、端末判別まで自前で書きました。((いつか紹介できればと思います))
最近は、Wi-Fi対応したフィーチャーフォンも増えてきたため、IPアドレス帯域で判別するべきか難しい判断ですが、未だに需要があると思っています。
とはいえ、肝心のサービスには直接関係しないバックグラウンドな機能なのでなるべく楽な方法で対応したいものですね。

参考URL

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*