多くのサイトはヘッダー、メイン、サイドカラム、フッターなどのパーツに分かれており、それぞれのパーツはページが変わってもメイン以外はほぼ同じの内容を表示しています。
例えばブログの場合、サイドバーに表示される内容は新着記事の一覧やカテゴリー一覧などが表示されていることが多いと思います。
通常 Laravel 5.0 では次のようにしてコントローラーから表示に必要な変数を受け取ります。
public function index() { $data = array(); $data['categories'] = Post::Category->all(); return view('index', $data); }
配列のキー部分が変数名になるので、Blade ビューでは「$categories」にカテゴリー一覧が格納されることになります。
しかし、サイトのページが1つしかないならこの方法でも構いませんが、実際には多くのページとそれに対応するコントローラがあり、サイドバーに表示するためだけに同じ記述をすべてのビューコントローラーに繰り返し書くのは良い方法ではありません。
そこで、View Composers を使い、それぞれパーツに対応するコントローラを作成することで、そのパーツが読み込まれるたびに必要な変数が自動的に用意されるようします。
まずはプロバイダー「ComposerServiceProvider」を作成します。
「app/Providers/ComposerServiceProvider.php」となるようにファイルを作成して下さい。
内容は次のようにします。
<?php namespace App\Providers; use View; use Illuminate\Support\ServiceProvider; class ComposerServiceProvider extends ServiceProvider { public function boot() { // } public function register() { // } }
boot() にビューに対応する処理を記述します。
方法は2種類あり、クロージャーを使ってこのファイルに直接書く方法と、コントローラーを指定して別ファイルに詳細を記述する方法です。
まずは単純にクロージャーを使ってサイドバーテンプレート「views/sidebar.blade.php」が読み込まれた際にカテゴリー一覧が取得できるようにしてみます。
public function boot() { View::composer('sidebar', function($view) { $view->categories = Category::all(); }); }
これでビューの $categories にすべてのカテゴリーが格納されます。
第一引数にはテンプレートファイルを指定します。もしテンプレートファイル sidebar.blade.php が layouts フォルダなどに入っている場合は第一引数を「layouts.sidebar」とします。
例では Category モデルを使っているのでファイルの最初に「use App\Category;」の記述を忘れないようにして下さい。
このままでは ComposerServiceProvider.php は読み込まれないので、「app/config/app.php」の providers に「App\Providers\ComposerServiceProvider」を追加します。
コンソールで「composer dump-autoload」とすると適用されます。
次に、コントローラーを指定して別ファイルで同じ処理をしてみます。
コントローラーは「app/Http/Controllers/ViewComposers/SidebarComposer.php」となるようにフォルダとファイルを作ります。
内容は次のとおりです。
<?php namespace App\Http\ViewComposers; use Illuminate\Contracts\View\View; use App\Category; class SidebarComposer { protected $categories; public function __construct() { $this->categories = Category::all(); } public function compose(View $view) { $data = array(); $data['categories'] = $this->categories; $view->with($data); } }
継承しやすいようにコンストラクタでカテゴリー一覧を取得しています。
compose() でビューに変数を渡しています。
コントローラーの作成が済んだら ComposerServiceProvider.php に戻り、boot() を次のようにします。
public function boot() { View::composer('sidebar', 'App\Http\ViewComposers\SidebarComposer'); }
第2引数には先ほど作ったコンポーザークラスへのパスを記述します。
これでパーツが読み込まれた際に自動的に SidebarComposer での処理が行われます。
処理が複雑な場合はコントローラーに、単純な場合はクロージャーに書くなど、目的に応じて使い分けることになると思います。