wp_is_mobile みたいなモバイル判定を baserCMS で
ここ数年、レスポンシブウェブデザイン(RWD)をサクッと実装できるCSSフレームワークも成熟してきて、baserCMSでのサイト構築でも積極的に取り入れている方が多いのではないかと思います。『baserマーケット』で配布されているテーマも、安定したダウンロード数を誇る『BCCOLORS』を筆頭にRWDのものが多いですよね。
さて、PC・タブレット・スマートフォンと、デバイス(というかブラウザ幅)に合わせて見た目を整えてくれるRWDですが、ときに「スマホで見るときに限り、このブロックは表示させたくない」というようなことってありませんか? CSSのメディアクエリで非表示にする方法があるとはいえ、パフォーマンスのことを考えたら、できれば非表示のブロックをPHPレベルで制御したいところです。
baserCMSにはデバイス判定の関数がない
PHPレベルでデバイス判定したいとき、環境変数 HTTP_USER_AGENT に含まれる文字列で判定する手法があります。WordPressにはその手法を取り入れた関数 wp_is_mobile() があったり、ブラウザを判定するグローバル変数 $is_iphone があったりと、ビルトインの関数・変数である程度の切り分けができるようになっています。
(タブレットとスマホが同一視されるというデメリット(?)もありますが)
ところが、baserCMSにはそうした手段が今のところ用意されていません。環境変数をもとに自前でロジックを組んでもよいのですが、一口に「モバイルデバイス」といってもOSや機種が事細かに分かれており、シビアに判定しようとすればするほど泥沼にはまっていくこと必至の情勢となります。
そこで、そうした面倒くささをサクッと解消してくれるライブラリの力を借りることにしましょう。
ライブラリ『Mobile_Detect』を自作ヘルパーに
ここで登場するのが、PC・タブレット・スマートフォンの判定はもとより、OSや機種なども細かく切り分けてくれる軽量のPHPクラス『Mobile_Detect』です。PC・タブレット・スマートフォンの切り分けだけなら
- isMobile()
- isTablet()
の二つのメソッドを使うだけでOKという、実に使い勝手のいいライブラリとなっています。
ドキュメントにもあるように、基本的には
- Mobile_Detect.php の読み込み
- インスタンス生成
- メソッドの返り値で判定
という使い方なので、テンプレートファイルに強引に組み込むのもアリなんですが、ここはCakePHPのお作法にのっとって行儀よくヘルパー化することにしましょう。
下準備
- 『Mobile_Detect』のGitHubリポジトリにて、ページ右側にある「Download ZIP」ボタンをクリック
- ダウンロードされたZIPファイルを展開し、現われたフォルダを「Mobile-Detect」にリネーム
- フォルダごと /app/Vendor 内にアップロード
git が使える環境なら、/app/Vendor 内で直接 git clone してもOKです。
コード例
ヘルパーファイル名を仮に FooHelper.php として、
- /app/View/Helper 内
- /app/webroot/theme/{使用中のテーマディレクトリ}/Helper 内
のいずれかに配置します。前者だとテーマが変わっても使用可能、後者だとそのテーマの中だけで有効となるので、必要に応じて配置場所を選んでください。
<?php /** * テーマヘルパー * テーマファイル内で $this->Foo->bar() のように記述して使う */ /** * 外部ファイルの読み込み */ App::import('Vendor', 'Mobile-Detect/Mobile_Detect'); /** * Foo ヘルパー */ class FooHelper extends BcAppHelper { /** * 閲覧中のデバイスを判定 * computer, tablet, phone のいずれかを返す */ public function mobileDetect() { $detect = new Mobile_Detect; if ($detect->isMobile()) { if ($detect->isTablet()) { $deviceType = 'tablet'; } else { $deviceType = 'phone'; } } else { $deviceType = 'computer'; } return $deviceType; } }
ここまでの仕込みが終われば、テーマファイル内で
<?php if ($this->Foo->mobileDetect() === 'computer'): ?> <!-- ここにPCで見たときだけ表示させたい内容 --> <?php endif ?>
といったかたちで閲覧中のデバイスによる表示内容の切り分けができるようになります。
ヘルパー名の Foo はCakePHPやbaserCMSが予約している名前以外なら変更OKです。その際は、ヘルパーファイル名やファイル内の Foo の箇所を一致させるようにしてください。
ではでは、ハッピーなbaserCMSライフを!
[2016.1.18 追記]
baserCMSにはデバイス判定の方法が内蔵されてないわけではない
baserCMSコアコミッター @n_1215 さんから情報をいただきました。
@tecking Mobile_Detectほど高性能じゃないですが実は設定値がございまして。 https://t.co/KRBtSMTu86 この設定を元にしてCakeRequestクラスからisSmartphone()とかisMobile()などの判定メソッドが使えます。
— n (@n_1215) January 18, 2016
ということで、別解として紹介します。
<?php if ($this->request->isSmartphone()) ?> <!-- スマホで閲覧しているときに表示させたい内容 --> <?php endif ?> <?php if ($this->request->isMobile()) ?> <!-- ガラケーで閲覧しているときに表示させたい内容 --> <?php endif ?>
@n_1215 さんがおっしゃるように多機能ではないですが(スマホ / タブレットの切り分けができない)、『Mobile Detect』の組み込みに比べればラクな方法なので、必要に応じて別解を採用してもよいかとおもいます。 どのようなUser-Agent のときに isMobile(), isSmartphone() でそれぞれで true を返すかはGitHubに公開されているソースをご参照ください。
[2016.1.20 追記]
@n_1215 さんからさらに情報をいただきました。
@tecking あとisSmartphone()等の判定メソッドは3.0.7で追加したので注意書き足しておいていただけると誤解がないと思います。
— n (@n_1215) January 20, 2016
ということで、isSmartphone(), isMobile() メソッドをお使いの際は、baserCMSのバージョンにお気を付けくださいませ。