こんにちは。ファガイです。本日は、LaravelのViewComposerに関してまとめます。
使用技術
- Laravel5
そもそもViewComposerとは?
ViewComposerはViewに対する表示準備を行うための機能です。
これを利用することで、Controllerで共通で取得する必要がある要素等を分離して対応することが出来ます。
(つまり、コントローラーの肥大化を防ぐ)
導入
Laravel5にはViewComposerの機能が含まれていますが、ファイルは用意されていません。
理由としては、書こうと思えばどこでも書けるからでしょう。
今回は、公式サイトに載ってあるComposerServiceProviderを利用します。
app/Providers
ディレクトリに ComposerServiceProvider.php
を作成します。
<?php namespace App\Providers;
use View; // Illuminate\Contracts\View\Factory
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Register bindings in the container.
*
* return void
*/
public function boot()
{
// ここにcomposerを使用する処理を記述します
// クラスベースのcomposer
View::composer('profile', 'App\Http\ViewComposers\ProfileComposer');
// クロージャーベースのcomposer
View::composer('dashboard', function($view)
{
});
}
/**
* Register
*/
public function register()
{
}
}
こんな感じですね。
あとは、ViewComposerを置いておくためのディレクトリを、作っておきましょう。app/Http/
以下にViewComposersディレクトリを作成しておきましょう。
また、ServiceProviderを作ったので、config/app.php
ディレクトリのprovidersにComposerServiceProviderを登録してください。
ViewComposerを作ってみる
では、実際にViewComposerを作成します。
今回は簡単なものがいいので、データの取得もやらないTitleComposerというものを作成してみます。
<?php namespace App\Http\ViewComposers;
use Illuminate\Contracts\View\View;
class TitleComposer {
/**
* @var String
*/
protected $title;
public function __construct()
{
$this->title = 'タイトル';
}
/**
* Bind data to the view.
* @param View $view
* @return void
*/
public function compose(View $view)
{
$view->with('title', $this->title);
}
}
これでTitleComposerが作成できました。
一応軽く説明すると、composeメソッドの第1引数には、Illuminate\Contracts\View\Viewインターフェース
に注入されているIlluminate\View\Viewクラス
が入ります。
これは、Controllerが呼び出された後に実行されます。
なので、実際は以下のように、セットされていたらそれに追加するみたいな処理も書けます。インターフェースにはメソッドが記載されていないので、IDE側で警告が出ますがね。。。
if($view->offsetExists('title')) {
$title = $view->offsetGet('title');
$view->with('title', $title. ' | ' .$this->title);
} else {
$view->with('title', $this->title);
}
では、ComposerServiceProviderに登録しましょう。
ComposerServiceProviderへの登録
ComposerServiceProviderへの登録には2種類あります。
普通はクラス名を渡す方法ですね。もう一つはクロージャーで呼び出す方法ですね。
今回は普通に登録します。
public function boot()
{
View::composer('*', 'App\Http\ViewComposers\TitleComposer');
}
これで、あとは対象のviewファイルで{{$title}}
を呼び出してみましょう。呼び出せましたよね?
登録方法に関して
View::composerメソッド等でのcomposerの登録に関してですが、以下のとおりです。
単純に登録する
View::composer('profile', 'App\Http\ViewComposers\ProfileComposer');
第1引数に入っているのはviewの名前です。viewメソッドと同様です。
第2引数にViewComposerを登録します。
複数のViewに対して登録する
View::composer(['profile', 'dashboard'], 'App\Http\ViewComposers\MyViewComposer');
上記の様に、配列にして渡すとOKです。最初に使っていた「*」は全てに適用する場合に使用します。
複数の設定を一気に登録する
View::composers
メソッドを利用します。
View::composers([
'App\Http\ViewComposers\AdminComposer' => ['admin.index', 'admin.profile'],
'App\Http\ViewComposers\UserComposer' => 'user',
'App\Http\ViewComposers\ProductComposer' => 'product'
]);
指定順番が逆になるので注意です。
クロージャーで登録する
クロージャーだと呼び出すクラスすら必要ないですね。
View::composer('profile', function($view) {
$view->with('profile', User::find(1));
});
クラス名で指定したようなやり方にするならこんな感じ。
View::composer('profile', function($view) {
$class = app('App\Http\ViewComposers\ProfileComposer');
$class->compose($view);
}
View Creator
ViewComposerはViewへのデータの入れ込み等が終わった後に呼ばれましたが、先にデータを入れておく方法も存在します。
それがViewCreatorです。
ServiceProviderを分ける必要も無いかもしれません。ただ、フォルダは別にした方が良さそう。
なお、ViewComposerと違うのは、呼び出すメソッドの違いです。
ServiceProviderで指定するメソッドは、 View::creator
メソッドとなります。そして、ViewCreatorクラスでは、composeメソッドではなく、creator
メソッドが呼ばれます。
最後に
ViewComposer便利ですねー。
コメント