Laraval Bladeの機能で擬似Layout

知ってる人には当たり前の話。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つ。

  1. @extends で送る先の View を指定する
  2. @yield と @section のセットでコンテンツを送り込む

1 がめちゃくちゃ強力。

Controller や Renderer 側で View の階層、機能を管理するという考え方じゃなくて blade 自体が Blade 全体の管理しているものをすべて知ることができる という考え方。

まー確かに実に PHP っぽい。ちょっと怖いけど。

これを利用して「名前空間を整理すると」layout というか container となる view をまとめておくことができそうだ。

app/views/containers/

みたいな。

参考

More