Laravelのビューでテンプレートを呼び出したり、部分的に指定したコードを表示するディレクティブとして、@extends, @include, @section, @yieldがあります。
ここではそれぞれの使い方を実例を交えて解説しています。
@extends
@extendsの使い方
@extendsは、引数でビューファイル名(ブレード名)を指定することで、指定したファイルの中身をそのまま表示するディレクティブです。
@extends('ビューファイル名')
記述した場所に、指定したファイルの中身をそのまま表示します。
ビューファイルが深い階層にある場合
ビューファイルがviewsの中のあるディレクトリの中に入っている場合は、ディレクトリ名記述し「.」でつないでファイル名を記述します。
例えば、「views > ディレクトリ1 > ディレクトリ2 > ビューファイル名.blade.php」という階層構造の場合は以下のようになります。
@extends('ディレクトリ名1.ディレクトリ名2.ビューファイル名')
実例
例えば、「views > layouts > base.blade.php」という階層にある「base.blade.php」があるとします。
<h1>見出し<h1>
この「base.blade.php」中身を、「index.blade.php」ファイルの中で呼び出す場合は、「index.blade.php」の中に以下のように記述します。
@extends('layouts.base')
<p>リード文</p>
↓ コンパイルすると、以下のようになります。
<h1>見出し<h1>
<p>リード文</p>
@include
@includeの使い方
@includeディレクティブは@extendsと同じく指定したビューファイルの中身を丸ごと表示することができます。
@include('ビューファイル名')
ビューファイルが深い階層にある場合
ビューファイルがviewsの中のあるディレクトリの中に入っている場合は、ディレクトリ名記述し「.」でつないでファイル名を記述します。
例えば、「views > ディレクトリ1 > ディレクトリ2 > ビューファイル名.blade.php」という階層構造の場合は以下のようになります。
@include('ディレクトリ名1.ディレクトリ名2.ビューファイル名')
呼び出したビューにデータを渡す(@extendsと@includeの違い)
ここまでだと@extendsと全く同じじゃないか。@includeなんて要らないとなります。ですが、@includeには大きな特徴があります。
それは、呼び出したビューにデータを渡せるということです。
データを渡す場合は第2引数で ['変数名'=>'値']
というように記述します。
@include('ビューファイル名', ['変数名'=>'値'])
すると、呼び出したビューの中の「$変数名」に指定した値が入ります。
また、@includeでは後述の@yieldは機能しません。
複数のデータを渡す場合
呼び出したビューファイルに複数のデータを渡す場合は、配列の中にプロパティと値のセットをカンマで区切って付け足していきます。
@include('ビューファイル名', [ '変数名1'=>'値1', '変数名2'=>'値2', '変数名3'=>'値3',,,,])
実例
例えば「views > template > heading.blade.php」という階層にある「heading.blade.php」が以下のようになっているとします。
変数「$title」があることに注目してください
<h1>{{ $title }}</h1>
「index.blade.php」で「heading.blade.php」を呼び出し、そのときに「$title」に「h1見出し」というデータを渡す場合は以下のように記述します。
@include('template', ['title'=>'h1見出し'])
<p>リード文<p/>
↓ コンパイルすると、以下のようになります。
<h1>h1見出し</h1>
<p>リード文<p/>
ビューファイルを条件分岐で出し分ける方法
@include
で存在しないビューを指定するとエラーになってしまいます。
そんなときは@includeの派生で@includeIf
や@includeWhen
などのディレクティブが用意されています。
これを使うと、対象のビューファイルが存在している場合は呼び出しを行い、存在しない場合は何もしないといった条件分岐をすることができます。
@includeIf
@includeifを使うと、指定したビューファイルが存在していれば、ビューファイルの内容を表示し、存在しなければ何もしないという処理を行えます。
@includeif('ビューファイル名', ['変数名'=>'値'])
@includeWhen
@includeWhenを使うと、真偽値を返す変数(あるいは真偽値自体)を指定して、その変数の値ががtrueの場合は指定したビューファイルをよびだし、falseの場合は何もしないという処理を行えます。
@includeWhen($boolean, 'ビューファイル名', ['変数名'=>'値'])
@includeUnless
@includeUnlessは@includeWhenの真逆です。
真偽値を返す変数(あるいは真偽値自体)を指定して、その変数の値ががfalseの場合は指定したビューファイルをよびだし、trueの場合は何もしないという処理を行えます。
@includeUnless($boolean, 'ビューファイル名', ['変数名'=>'値'])
@includeFirst
@includeFirstを使うと、配列形式でビューファイルを複数指定することができます。
最初のビューファイルから順に存在確認していき、存在しているビューが見つかった時点でそのファイルの内容を表示します。
@includeUnless( ['ビューファイル名1', 'ビューファイル名2',,,, ], ['変数名'=>'値'])
@yieldと@section
@yeildと@sectionは@extendsとセットで使います。
ビューファイル全体ではなく、部分的な要素だけを表示したい場合や、読み込んだファイルによって表示する内容を変えたい場合に使います。
@yieldとは何か?
@yieldは@extendsで呼び出すビューの中に記述します。第1引数でセクション名を指定します。
すると、@extendsが記載してあるファイルに記載してある対応する@sectionの内容が@yieldの部分に入ります。
なお、「yield」とは「生み出す」という意味の英語です。
このため、Laravelにおいては、指定したセクションをビューファイルの指定した場所に生み出す(呼び出す)という意味になります。
@yield(セクション名)
@sectionとは何か?
@sectionは@extendsで呼び出したビューファイルの中の、対応する@yeildに情報を表示するためのディレクティブです。
データやコードなどの情報を記載します。ビューファイルのような役割です。
@sectionの使い方には主に次の2つがあります。
変数にデータを渡す
@yeiledで指定したセクションに、文字列などのちょっとしたデータを渡したいときは、第2引数で渡したいデータ指定することができます。
@section('セクション名', 渡すデータ )
ブレード(HTML)のコードを渡す
@yeiledで指定したセクションに、HTMLなどのコードを渡したい場合は、@sectionと@endsectionの間にコードを記述します。
@section('セクション名') コード @endsection
@sectionと@yieldを使う手順
@sectionと@yieldを使うための基本的な手順は以下のようになります。
@sectionと@yieldの注意点
同じファイルの中に記述しても機能しない
@extendsを使わずに、@yieldを記述してあるのと同じファイルに@sectionを記載しても機能しません。
例えば以下のようにセクション名「lead」に対する@yieldと@sectionを記載しても指定した内容は表示されません。
<p>@yield('lead')</p>
@section('lead', 'リード文です。')
yieldのスペルミスに注意
@yieldは日本人があまり使わない英語です。これを「@yeild」といったようにスペルミスして記述すると、正しく動かなくなります。
画面上にスペルミスした状態の文字列が表示されます。
例えば、次のような記述のあるファイルを@extendsで読み込んだ場合は以下のようになります。
<h1>@yeild('headline')</h1>
▼ブラウザの表示
対応するセクションがないと何も表示されない
@yieldで指定したセクション名が存在しない場合やスペルミスしている場合は、画面上に何も表示されません。
@yieldと@sectionのセクション名が一致しているかどうかは非常に重要です。
複数@extendsする場合は表示される順番に注意が必要
@extendsで複数のビューファイルを呼び出す場合は、下に記述されているものから上に表示されます。
例えば、index.blade.htmlで@extendsを使って、header, contents, footerのビューを以下のように読み込むとします。
@extends('template.header')
@extends('template.contents')
@extends('template.footer')
すると、画面には、footer → contens → headerの順番で表示されます。
@sectionと@yieldの実例:変数にデータを渡す
@yieldに対して、@sectionで定義したデータを渡す場合は、@sectionを以下のように記述します。
@section('セクション名', 渡すデータ )
実例
例えば、「views > template > heading.blade.php」というパスの「heading.blade.php」ファイルに@yield('headline')
と記載してあるとします。
<h1>@yield('headline')</h1>
これは、@extendsで呼び出されたときに、そのファイルに@sectionでセクション名「headline」の内容を表示するという記述です。
この「heading.blade.php」を「views > index.blade.php」で@extendsで呼び出します。
@extends('template.heading')
このままでは、呼び出した内容は<h1>@yield('headline')</h1>
のままです。
この@yieldに内容を渡すための@sectionを追記します。
@extends('template.heading')
@section('headline', 'h1見出しです')
こうすることで、@yieldのセクション名「headline」に対象となる@sectionで指定したデータ「h1見出しです」が入ります。
「index.blade.php」のコンパイル結果は以下のようになります。
<h1>h1見出しです</h1>
ブラウザの表示
@sectionと@yieldの実例:コードを渡す場合
@yieldに対して、@sectionで定義したブレードのコードを渡す場合は、@sectionと@endsectionの間にコードを記述します。
@section('セクション名') コード @endsection
実例
例えば、「views > template > heading.blade.php」というパスの「heading.blade.php」ファイルに@yield('header')
と記載してあるとします。
<body>
@yield('header')
</body>
これは、@extendsで呼び出されたときに、そのファイルに@sectionでセクション名「header」の内容を表示するという記述です。
この「heading.blade.php」を「views > index.blade.php」で@extendsで呼び出します。
@extends('template.heading')
このままでは、呼び出した内容は<body>@yield('header')</body>
のままです。
この@yieldに内容を渡すための@sectionを追記します。
@extends('template.heading')
@section('header')
<h1>ページの見出しです</h1>
<p>リード文です</p>
@endsection
こうすることで、@yieldのセクション名「header」に対象となる@sectionと@endsectionで囲まれた部分のコードが入ります。
「index.blade.php」のコンパイル結果は以下のようになります。
<h1>ページの見出しです</h1>
<p>リード文です</p>
ブラウザの表示
実例:複数@extendsする場合は表示される順番に注意が必要
@extendsで複数のビューファイルを呼び出す場合は、下に記述されているものから、呼び出し先のビューファイルの中で表示されます。
例えば、index.blade.htmlで@extendsを使って、views > templateディレクトリにある3つのファイル、header.blade.php, contents.blade.php, footer.blade.phpがあるとします。
<header>
-----------------------<br>
ヘッダーです。
@yield('header')
<br><br>
</header>
<div>
-----------------------<br>
コンテンツです。
@yield('contents')
<br><br>
</div>
<footer>
-----------------------<br>
フッターです。
@yield('footer')
<br><br>
</footer>
上記の3つのファイルを、index.blade.phpの中で次のように順番に読み込むとします。
@extends('template.header')
@extends('template.contents')
@extends('template.footer')
index.blade.phpには各@yieldに表示するためのデータも@sectionで記述します。
@extends('template.header')
@extends('template.contents')
@extends('template.footer')
@section('header')
<h1>ページタイトル</h1>
@endsection
@section('contents')
<p>本文です。</p>
@endsection
@section('contents')
<p>フッターです</p>
@endsection
これをコンパイルすると画面の表示配下のようになります。
footer -> contents -> headerの順に表示されていることがわかります。つまり、@extendsは下に記載してあるものから、順に表示されます。
ヘッダーを上にしたい場合はindex.balde.phpの@extendsの順番を以下のように修正する必要があります。
@extends('template.footer')
@extends('template.contents')
@extends('template.header')
こうすることで、header -> contents -> footerの順に表示されるようになります。