知ってる人には当たり前の話。After Rais の世界の View の Layout という考え方はどれも同じようなものかと思っていたのだが、意外とそうでもなかったというメモ。
LaravelはController側でLayoutの制御を支援してない
Layout を Controller の property で指定する機能はあるが、Rails の view のように render の際に layout を指定する機能はないため、Action 側でコントロールするのはやや難しい。
abstract class Controller
{
..
protected $layout;
..
protected function setupLayout() {}
..
public function callAction($method, $parameters)
{
$this->setupLayout();
$response = call_user_func_array(array($this, $method), $parameters);
..
}
}
こんな感じ。Action に渡ってくる際にはもう layout の解決は済んでしまっている。
むしろこの辺は Blade 自体が柔軟というか強力すぎる機能を提供している。
Bladeはdirectiveで@extendsする
@extends, @section, @yield を利用して特定の view の特定の領域にコンテンツを inject することを global に許可しているので、layout というか自身の container になる view を view の中から指定することができる。
例えば以下のような感じになる。
in layout.blade.php
@yield('content') // <-- ここに @extends した側の @section のコンテンツが入る
in contents.blade.php
@extends('path.to.layout') // <-- ここで container になる blade の名前を指定
@section('content')
.. <-- この中身が @yield に置換される
@stop
ポイントは以下の2つ。
- @extends で送る先の View を指定する
- @yield と @section のセットでコンテンツを送り込む
1 がめちゃくちゃ強力。
Controller や Renderer 側で View の階層、機能を管理するという考え方じゃなくて blade 自体が Blade 全体の管理しているものをすべて知ることができる という考え方。
まー確かに実に PHP っぽい。ちょっと怖いけど。
これを利用して「名前空間を整理すると」layout というか container となる view をまとめておくことができそうだ。
app/views/containers/
みたいな。