Laravel 5.1 入門記 その8(Views 編)
今回は Views です。
Views - Laravel - The PHP Framework For Web Artisans
Basic Usage
やっとテンプレートの話に突入。
コントローラからプレゼンテーションロジックを分離するために view を使います。 view は resources/views に配置します。では早速、サンプル通りのファイルを resource/views/greeting.php に作成します。
<html>
<body>
<h1>Hello, <?php echo $name; ?></h1>
</body>
</html>
続いて、 routes.php に新しいルーティングを追加します。
Route::get('greeting', function () {
return view('greeting', ['name' => 'James']);
});
そして、http://localhost:8080/greeting にアクセスすると
Hello, James
と表示されました\(^o^)/
return view('greeting', ['name' => 'James']);
この view 関数でテンプレート名と、テンプレートに渡すパラメータを定義してあります。テンプレート名は resources/views 以下の php ファイルを探しに行き、ディレクトリ階層がある場合は / では無く、ドットで区切って指定を行います。
もし view 全体にパラメータを設定して共有したいときは、AppServiceProvider の boot メソッドに定義を追加します。これも試してみます。 app/Providers/AppServiceProvider.php を次のように修正します。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
view()->share('my_name', 'tnamao');
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}
続いて、 resources/views/greeting.php を次のように編集します。
<html>
<body>
<h1>Hello, <?php echo $name; ?>. I'm <?php echo $my_name; ?></h1>
</body>
</html>
そしてブラウザでアクセスすると…
Hello, James. I'm tnamao
共有パラメータも表示できました \(^o^)/
View Composers
View Composer は View の共通処理(例えばヘッダーとかに表示する情報やサイドバーの情報など)を一箇所にまとめて提議するためのものらしい。画面を Widget 的なもので構成するときに特に役に立つのかなと思った。
まずは簡単な、Closure での View Composer を定義してみます。app/Providers/ComposerServiceProvider.php を作成し、内容は以下の様にします。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* コンテナ結合の登録
*
* @return void
*/
public function boot()
{
// クロージャーベースのコンポーサーを使用する
view()->composer('greeting', function ($view) {
$view->with('composer_value', 'greeting composer!!');
});
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}
新しい Service Provider を作ったら app/config.php の providers に登録の必要があるため、 provides の配列に以下を追加します。
App\Providers\ComposerServiceProvider::class
続いて、 resources/views/greeting.php に View Composer で設定した値を表示するコードを追記します。
<html>
<body>
<h1>Hello, <?php echo $name; ?>. I'm <?php echo $my_name; ?></h1>
<p>compoer_value: <?php echo $composer_value; ?></p>
</body>
</html>
そしてブラウザで http://localhost:8080/greeting にアクセスすると
Hello, James. I'm tnamao
compoer_value: greeting composer!!
\(^o^)/
View Composer は登録した時の第1引数で指定した値に一致する view が呼ばれた時にのみ実行されるようです。
view()->composer('greeting', function ($view) {
これですね。では、本当にそうなるのか、この greeting を残したまま、他の定義を ComposerServiceProvider に追加してみます。
view()->composer('hogehoge', function ($view) { $view->with('composer_value', 'hogehoge composer!!'); });
view()->composer('greeting', function ($view) { $view->with('composer_value', 'greeting composer!!'); });
変更後にブラウザでアクセスすると
Hello, James. I'm tnamao
compoer_value: greeting composer!!
と、無事に追加分の影響がありませんでした。ちなみに View Compoer が同じ View に複数定義されてしまった場合も見てみます。
view()->composer('greeting', function ($view) { $view->with('composer_value', 'greeting composer!!'); });
view()->composer('greeting', function ($view) { $view->with('composer_value', 'hogehoge composer!!'); });
前後を入れ替えて、どちらも view()->composer の第1引数を greeting にしてみました。これで表示を確認すると…
Hello, James. I'm tnamao
compoer_value: hogehoge composer!!
複数の View Composer を登録しても問題無いようで、登録した順番に実行されるので、同じ変数の場合は上書きされてしまうようです。
続いて View Composer を Closure ではなく、クラスに実装する方法です。View Composer を実装するクラスは、特に置く場所は決まっていないため、適当な場所に作ります。今回はドキュメントにならって、app/Http/ViewComposers/ProfileComposer.php に実装します。
<?php
namespace App\Http\ViewComposers;
use Illuminate\Contracts\View\View;
class ProfileComposer
{
public function __construct()
{
// Dependencies automatically resolved by service container...
}
/**
* Bind data to the view.
*
* @param View $view
* @return void
*/
public function compose(View $view)
{
$view->with('composer_value', 'class composer!!');
}
}
実装したのは compose メソッド。続いて、ComposerServiceProvider にこのクラスを登録します。Closure で設定していたものは削除して、代わりに次の定義を追加しました。
view()->composer('greeting', 'App\Http\ViewComposers\ProfileComposer');
これで Closure と同じように登録完了です。ちなみに compose メソッドに実装を行いましたが、この composer に登録するときに @methodName とすれば、 compose メソッド以外でも登録可能です。
同一の View Composer 実装を複数の View に適用したいときは以下の様に 第1引数に array で対象の View 名を渡してあげれば適用されます。
view()->composer(['greeting1', 'greeting2'], 'App\Http\ViewComposers\ProfileComposer');
View Creators
View Creator はインスタンスが作られた直後に呼ばれるもので、View Composer のようにレンダリング時に実行されるものとは異なるらしい。
view()->creator('profile', 'App\Http\ViewCreators\ProfileCreator');
ComposerServiceProvider での登録はこんな感じで、create メソッドが呼ばれるらしい。恐らくメソッド名も変更可能なはず。試してないけど!
Views についてはここまで。次は Blade Templates やっとテンプレートエンジンの説明か〜 長かった。