componentを活用して再利用可能なviewを作成する【Laravel】

公開日:

最終更新日:

componentを活用して再利用可能なviewを作成する【Laravel】

わたしは元々テンプレートエンジン(例えばsmartyやPHPに限定しなければejsなど)をあまり使ってこなかった人間なので、HTMLの直書きでコードを量産することが多かったです。

なのでPHPを覚えはじめの頃は「includeするだけでこんなに簡単にコードが量産できたりメンテナンスが楽になるとは・・・」といった感動がありました。

LaravelはPHPベースのフレームワークでviewにもPHPが利用できます。
今までのようにincludeで対応することもできるのですが、せっかくなのでBladeテンプレートを利用して記述もスッキリとさせましょう。

今回はBladeテンプレートの機能としてよく利用しているcomponent(コンポーネント)について書いていきたいと思います。
ちなみに環境はLaravel5.6としています。

componentを使ってみる

使い方としては特別に何かをするわけではなくBladeテンプレートの規則に従って、ファイル名に.blade.phpというようにしておけばいいだけです。
componentの読み込み方は、@component(‘path’)とviewファイルに記述するだけで読み込みが完了です。(pathの部分はご自身のディレクトリ構成に合わせて書き換えてください。)
componentは@sectionなどと同じように、終了する際は必ず@endcomponentと記述しなければいけません。

bladeを作成

簡単に作成の手順として書いていきます。
今回はBootstrapでよく利用するモーダルを例にあげますが、基本的にタグの入れ子が多いのでviewにベタ書きしてしまうとかなり邪魔くさいです。

また、モーダルを複数設置したい場合は基本的に同じ記述をしてidを割り振るだけの作業なので、コピペで構築するには非常に効率が悪いしコードも読みづらいです。

なので、共通部分はcomponent化してしまってidやclassの割り振りに関しては@slotで管理してしまうといった形にしたいと思います。
ファイル名はmodal.blade.phpとでもしておきましょう。

<div class="modal fade" id="{{ $modal_id }}" tabindex="-1" role="dialog">
  <div class="modal-dialog modal-lg modal-dialog-scrollable modal-dialog-centered" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h3 class="modal-title">{{ $modal_title }}</h3>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">×</span>
        </button>
      </div>
      <div class="modal-body {{ !empty($modal_body_class) ? $modal_body_class : '' }}">{{ !empty($modal_body) ? $modal_body : '' }}</div>
    </div>
  </div>
</div>

slotを設定して出力する

基本的に$から始まっているものは@slot(‘変数名’, パラメータ)でcomponentに値を渡すことができます。
modal.blade.phpには記述していませんが、{{ $slot }}としておけば@component内に記述しているslot以外の内容が展開されます。

ひとまずtest.blade.phpを作成してモーダルを出力します。
Formクラスで生成している部分はLaravelCollectiveというプラグインを使用しているので、必要であればインストールしてみてください。
ちなみにFormのスタティッククラスではなく、実際にはvendor\laravelcollective\html\src\FormBuilderクラスを参照しています。記述としてはこんな感じです。

@component('components.custom_modal')
  @slot('modal_id', 'testModal')
  @slot('modal_title', 'test')
  @slot('modal_body_class', '')
  @slot('modal_body')
    {!! Form::open(['url' => 'test', 'method' => 'post', 'class' => 'text-center']) !!}
      {!! Form::hidden('id', $test->id) !!}
      {!! Form::button('SUBMIT',['type'=>'submit', 'name' => 'agree', 'class' => 'btn btn-success h4 px-5', 'value' => 'test']); !!}
      {!! Form::button('CLOSE',['type'=>'submit', 'class' => 'btn btn-secondary h4 ml-3 px-5', 'data-dismiss' => 'modal']); !!}
    {!! Form::close() !!}
  @endslot
@endcomponent

モーダルで作成している内容はいまいちな感じですが、このように書くと$の部分に値が挿入されてcomponentのHTMLが生成されます。
@slot(‘modal_body’)の部分はあえてslotにせずに{{ $slot }}で置き換えてもいい気はしますね。
第二引数で値を指定せずに@endslotとしておけば、その間に記述された内容が出力される仕組みになっています。

まとめ

冒頭に書いた通りincludeでも対応はできますが、ある程度ドキュメントのルールや本来ある便利な機能を使用する方が、後からコードを見返したときにどういう処理をしているのかわかりやすくなります。

また、本来の機能を利用してコーディングルールを決めておくことで、人によって書き方が異なったり、ファイルの影響範囲がどこまであるのかわからないといった事象も未然に防ぐことができると思います。

componentで使い回しができるパーツを用意しておけば、レイアウトの変更や修正などがあってもほぼview一つで完結できるので非常に便利です。
例えば全文検索で該当箇所を探すときも@slotを頼りに検索できるので、かなり探しやすくなるのではないでしょうか。

特にシステム開発ではフロント部分よりもバックエンドに時間を使いたい場合が大半を占めると思いますので、うまく既存の機能を利用して開発速度をあげていきましょう。

関連記事