【Laravel】@sectionと@yieldの使い方!includeやcomponentの違いを理解する
この記事からわかること
- bladeテンプレートとは?
- @sectionや@yieldの使い方
- 各ディレクティブの違い
- 役割や使うべき例
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
PHPのフレームワークである「Laravel」を学習していてレイアウトやテンプレート関係がややこしかったので自分なりにまとめてみたいと思います。
Laravelのblade(ブレード)テンプレートとは?
Laravelではblade(ブレード)という独自のテンプレートエンジンを使っています。独自の構文を使ってコードを記述するだけで簡単にレイアウトの使い回しやコンポーネントの再利用ができるようになります。
ファイル名(例) : header.blade.php
bladeテンプレートエンジンが動作するファイルは拡張子の前に.blade.php
と名のついたファイルです。(Laravelが組み込んである前提です。)
そのbladeファイルを「resource」>「views」の中に格納していき使用していきます。
blade(ブレード)テンプレート・まとめ
- Laravel独自のテンプレートエンジン
- 拡張子の前に「blade」
- 独自の構文を使用して記述する
- レイアウトの使い回しやコンポーネントの再利用
bladeテンプレートエンジンの使い方
bladeテンプレートエンジンを使いこなすには2つのファイルが必要になります。
- 親テンプレートファイル(パーツ分用意)
- 子テンプレートファイル(ページ分用意)
親テンプレートファイル
- ページの骨格になる部分を記述するファイル
- head内やfooter部分など定型的な部分を記述する
- 使いまわせる部品をあらかじめ作って置く
子テンプレートファイル
- ページのコンテンツ部分
- 定型ではなく、内容が異なる部分を記述
- パーツをうまく再利用して組み込む元になる部分
どっちが親でどっちが子になるかの理解がややこしいですが、親側を継承して子供側にはめ込んで使っていくのがbladeテンプレートの基本のようです。
テンプレート作成の流れ
ここで一度ファイル構造と作成の流れを確認してみます。
├── Laravelプロジェクト
│ ├── app
│ ├── resource
│ ├── css
│ └── views
│ // 子テンプレート(コンテンツ部分)
│ ├── page1.blade.php
│ ├── page2.blade.php
│ │
│ // 別フォルダ(layouts)の中に親テンプレートをまとめる
│ └── layouts
│ ├── head.blade.php
│ ├── page_header.blade.php
│ ├── footer.blade.php
│ ├── sidebar.blade.php
│ └── origin.blade.php
- 親テンプレートを作成し、再利用可能な部品生成
- 可変的な部分(コンテンツ)の表示場所を定義
- 子テンプレート(コンテンツ)を作成
- 親テンプレートを読み込み、定義した場所に子テンプレートを反映
使い回しになる親テンプレートは別フォルダ(今回はlayouts)の中にまとめておくと便利です。親を読み込みながら表示させるコンテンツ部分は「views」直下に作成していきます。
layoutsフォルダの中にはwebページの各パーツ部分(headerなど)とそれを集約した「origin.blade.php(名前は自由)」を用意しておきます。各パーツ部分は以下のように通常のHTMLをパーツごとに細切れにした状態で記述しておきます。
header.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/style.css">
</head>
footer.blade.php
<footer class="footer">
<p>ame ©︎ Copy Right 2022 </p>
</footer>
</body>
</html>
同様に「page_header.blade.php」なども用意したら1つのファイルに以下のように集約させておきます。
origin.blade.php
@include('layouts.header')
@include('layouts.page_header')
@yield('main')
@include('layouts.sidebar',['SideList'=>$MiddleList['SideList']])
@include('layouts.footer')
記事ページは集約させた「origin.blade.php」を継承して以下のように記述していきます。
page1.blade.php
@extends('layouts.origin')
@section('main')
<h1>記事1</h1>
<p>これは1つ目の記事です。</p>
<p>ご覧いただきありがとうございました。</p>
@endsection
作成した各パーツ達を集約させたり、レイアウトを継承するために使うのが@XXXXXで始まるbladeテンプレート特有のディレクティブたちです。
bladeで使えるディレクティブ
blade内では決まったディレクティブを記述することで、bladeファイルを上書きしたり、読み込んだり、継承したりすることが可能になります。directiveとは「指示文」や「構文」と言った意味を持つ英単語です。
基本となるディレクティブ
- @yield
- @section
- @include
- @component
@yieldディレクティブの役割と使い方
使う場所:親テンプレート
役割:同名の@sectionで定義された内容を表示させる
@yieldディレクティブは@sectionディレクティブとセットで使います。親側の表示させたい場所に@yieldディレクティブを記述することで子側に記述されている@sectionで囲まれた内容を表示させることができます。
@yield('名前')
名前は@sectionと同名であれば何でもOKです。「yield」の読み方はイールド、日本語に訳すと「与える」という意味になります。
@sectionディレクティブの役割と使い方
使う場所:主に子テンプレート(親も使う)
役割:同名の@yieldで定義されている場所にはめ込む内容区画を宣言する
@sectionを使ってyieldに渡す内容を定義できます。プレーンなテキストだけであれば第二引数に文字列を渡すだけでOKです。
@section('名前','テキスト')
HTML要素を渡す際は@section
と@endsection
をセットで使用し間に挟まれた内容をyieldに渡します。
@section('名前')
<h1>テキスト</h1>
<p>テキスト</p>
@endsection
また子テンプレートではなく親テンプレートで使う際は記述方法が異なり、@endsection
ではなく@show
でセクションの終わりを宣言します。@yieldの代わりに@sectionを使うイメージです。
●親テンプレートに記述するとき
@section('名前')
$msg_area
@show
親テンプレートで@section〜@show
(親section)を使用した場合は、子テンプレートに同名の@section〜@endsection
(子section)部分があれば親sectionを子sectionが上書きします。
上書きの際に親の内容も引き継ぎたい時は子section側に@parent
ディレクティブを設置します。
●親sectionの内容を子sectionで継承しつつ上書きする
@section('名前')
@parent
@endsection
@includeディレクティブの役割と使い方
sectionは囲まれた内容(bladeファイルの中の一部)をyieldに渡すディレクティブでしたが、bladeファイル全体を読み込ませることもできます。それが@includeディレクティブ
です。
使う場所:親/子
役割:引数に指定したbladeファイルを全て読み込む
@include('ファイル名')
@include('フォルダ名.ファイル名')
引数に読み込みたいファイル名を記述します。該当ファイルが「views」フォルダをカレントディレクトリとした時にフォルダの中にあればフォルダ名.ファイル名
の形式で記述します。ちなみに「include」は「含める、組み込む」といった意味の英単語です。
先ほどは@includeを使ってlayoutsフォルダの中の各パーツを「origin.blade.php」に集約していました。
また@includeのように読み込んだファイルを別ファイルでそのまま表示させることを「サブビュー」と言います。
@includeディレクティブで変数を受け渡す
指定したbladeファイルをそのまま読み込ませる@includeですが、変数を受け渡すことも可能です。例えばchild内に空の変数を定義しておき、parent側から変数の中身を渡すことでchildの内容を可変的なものにすることも可能です。
child.blade.php
<div>
<h1>{{ $title }}</h1>
<p>{{ $text }}</h1>
</div>
parent.blade.php
@include('child',['title'=>'これはタイトルです','text'=>'これはテキストです'])
parent側から変数を渡す際は第二引数に連想配列形式で値を渡します。キー値はchildの変数名と同じものにします。また連想配列にはparent側の変数を渡すことも可能です。
<?php $title = "これはタイトルです"; $text = "これはテキストです"; ?>
@include('child',['title'=>$title,'text'=>$text])
@componentディレクティブの役割と使い方
ファイル全体を読み込むディレクティブの中でも@componentディレクティブ
を使えばさらに自由なデータを受け渡すことができます。基本的なことは@includeと同じです。
使う場所:親/子
役割:引数に指定したbladeファイルを全て読み込む
先ほど同様にchildとparentを用意します。
child.blade.php
<div>
{{ $msg_area }}
</div>
parent.blade.php
@component('child')
@slot('msg_area')
<h1>テキスト</h1>
<p>テキスト</p>
@endslot
@endcomponent
@componentでは変数への値の受け渡しを連想配列ではなく、@slotディレクティブ
で行います。それにより文字列のみに捉われずHTML要素などがそのまま渡すことが可能になります。
@extendsディレクティブの役割と使い方
子テンプレートに集約させた親テンプレートを継承させるのが@extendsディレクティブ
の役割です。
使う場所:子テンプレート
役割:親テンプレートを継承する
使用方法は@includeなどと同じで第一引数にファイル名、第二引数には連想配列で変数への値の受け渡しも可能です。
page1.blade.php
@extends('layouts.origin')
@section('main')
<h1>記事1</h1>
<p>これは1つ目の記事です。</p>
<p>ご覧いただきありがとうございました。</p>
@endsection
最後にLaravel学習におすすめの参考書を紹介します。「PHPフレームワーク Laravel入門 第2版」は実際に私がLaravel学習に使用した参考書です。レビューはこちらにまとめてありますので参考にしてください。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。