こんにちは。エンジニアのたべたつです。
弊社では開発のほとんどでLaravelを使用しています。LaravelはデフォルトではテンプレートはBladeが使われます。
Bladeでは以下のようにレイアウトで枠組みを作成して、個別の画面ではextendsディレクティブを用いて内容を流し込んで使うことができます
layout.blade.php
@yield('content')
index.blade.php
@extends('layout') @section('content') <div>hoge</div> @endsection
sectionを使った時の問題点
とても便利な仕組みですが、1つ問題があり、読み込む側のファイルでsectionの実装を忘れてしまった際に気がつくことができません。以下のように実装をしてもエラーになりません。
index.blade.php
@extends('layout') <!-- 実装を忘れてしまった -->
実装をし忘れても、ブラウザに表示されるので気が付けるだろう、と思うかもしれませんが、メタタグなどブラウザに直接表示されない項目の場合、開発者ツールでHTMLを覗き込まないといけません。(もしくは、リリース後にメタタグがない、と誰かに指摘されてようやく気がつきます)
解決法
hasSection、もしくはsectionMissingディレクティブの中で例外をスローする方法で事前に実装忘れを回避できます。
layout.blade.php
@hasSection('meta') @yield('meta') @else @php throw new Exception() @endphp @endif
もしくは
@sectionMissing('meta') @php throw new Exception() @endphp @endif
しかし、これでは表示される例外のメッセージが情報不足で、開発者は困惑してしまいますので $this->lastCompiled
から対象のbladeファイルを取り出してあげることでエラーメッセージをいい感じにすることができます。
layout.blade.php
throw new Exception(array_shift($this->lastCompiled) . ' does not have "meta" section')
おわりに
ここまで書いて、振り返ったら仕組みとしてはテンプレートメソッドパターンと同じであることに気がついたので、カスタムディレクティブとテンプレートメソッドパターンを用いて、よりviewを見通しよくする方法を次回実践してみたいと思います。