Webサイトを構築していると同じURLでも、デバイス毎に呼び出すViewを変えるという事がよくあります。
(UserAgentで判定してPC版とスマホ版を出し分ける。みたいな。)
今回Laravel4でその辺やってみたので、その時のメモ。
※もしもっとスマートなやり方有れば是非教えて下さい。
要件
・View::make()で呼び出しはPC版・スマホ版同様にする
例:View::make('home');
・スマホ版になくてPC版にあるページがある場合はPC版を表示
・ViewComposerはPC版・スマホ版共通
弄くるファイル達
app
- views
home.blade.php ・・・home.blade.phpはPC版・スマホ版どちらもある
bye.blade.php ・・・bye.blade.phpはPC版のみある
- composer ・・・ViewComposerは共通
BaseComposer.php
- sp ・・・スマホ用のview置き場
home.blade.php
- routes.php
bootstrap
start.php
サンプル
1.何はともあれルーティング
// これはPC版、スマホ版どちらも存在するページ
Route::get('/', function()
{
return View::make('hello');
});
// こちらはPC版しかないページ
Route::get('/bye', function()
{
return View::make('bye');
});
2.デバイス判定用の処理
※こんな判定用クラスがあり「Device」で呼び出せるようFacadeの登録はしてあるとします。
class DeviceCheck
{
public static function isSmartPhone()
{
// なんらかの判定処理
}
}
3.bootstrap/start.phpに追記
<?php
$app = new Illuminate\Foundation\Application;
/*
| 途中省略します
*/
if (DeviceCheck::isSmartPhone()) {
App::bindShared('view.finder', function ($app) {
$paths = [
app_path('views/sp'),
app_path('views')
];
return new \Illuminate\View\FileViewFinder($app['files'], $paths);
});
}
return $app;
ポイントはapp/config/app.php
のprovidersに記述されているIlluminate\View\ViewServiceProvider
のコンストラクタが呼び出される前に
App::bindShared('view.finder', ・・・
することです。
View::make()時にパスを解決する箇所を追っていくと
Illuminate\View\FileViewFinder#find()
が呼び出されているのが分かる。
このクラスのコンストラクタでセットされる$paths内を順に照会していくので渡す配列の値の順序も重要。
$paths = [
app_path('views/sp'),
app_path('views')
];
が
$paths = [
app_path('views'),
app_path('views/sp')
];
だとviews直下から照会されるのでPC版が表示される。
スマホ版に無いページは404ページを表示させるならapp_path('views/sp')
のみにする。
以上です。