#@sectionとは
Laravel 5.8 Bladeテンプレートによると、
@section
ディレクティブは名前が示す通りにコンテンツのセクションを定義し、(中略)します。
とのこと。しかし、そのディレクティブの閉じ方は複数ある模様。Bladeでコンテンツの挿入を開始するによると、
セクションは常に
@section
で開始されます.
第二引数でコンテンツを指定する場合を除いて、
@section
は下記の5つの方法のうち、いずれかの方法で終了させなければなりません
@stop
セクションへの挿入を終了する.
@endsection
@stop
のエイリアスです
@show
Bladeテンプレートで現在のセクションを取得する.
@append
レンダリングを停止してセクションを追加する.
@overwrite
コンテンツの挿入を停止してセクションを上書きする.
の5手段があるようだが、それぞれがどのような意味を持つのかを、自分なりにまとめてみた。
なお、下記の例ではこのようなディレクトリ構造を想定して記載する。
resources
+--views
+--example
| +--index.blade.php ...子テンプレート
+--layouts
+--layout.blade.php ... 親テンプレート
##@show
@show
は、bladeテンプレート内でレンダリングされる。つまり、**@show
で閉じていない@section
ディレクティブは反映されない。**だからこそ、「親テンプレート」や「ベースレイアウト」では@show
を使い、「子テンプレート」や「継承レイアウト」では@stop
や@endsection
を使用するとの説明がされることが多い。
###例 show-1
親テンプレートに@show
を使用して、子に@parent
を使用した場合
おそらく、例中で最も思った結果になる方法だと思う。
@extends('layouts.layout')
<p>例1</p>
@section('hoge')
@show
@section('hoge')
@parent
hoge
@endsection
####結果
<body>
<p>例1</p>
hoge
</body>
親の@section
~@show
を引き継ぎつつ子の@section
~@endsection
に置き換えている。
###例 show-2
親テンプレートに@show
を使用しただけの場合
これは失敗例。@parent
を忘れた場合。
@extends('layouts.layout')
<p>例2</p>
@section('hoge')
@show
@section('hoge')
hoge
@endsection
####結果
<body>
<p>例2</p>
</body>
親の@section
~@show
が子の@section
~@endsection
に置き換えているため、レンダリングされないまま出力された。
###例 show-3
失敗例?その2。
子に@show
を、親に@endsection
付けた場合
<p>例3</p>
@section('hoge')
@endsection
@extends('layouts.layout')
@section('hoge')
hoge
@show
結果
<body>
hoge
<p>例3</p>
</body>
推測では、子の@section
~@show
が継承前にレンダリングされ、その後親の@section
~@endsection
を処理したため、親のレイアウトより優先されて<body>
タグの直下に子の@section
~@show
の内容が反映されたのではないかと思う。
(文献がないから推測の域を出ないけど...。)
##@stop,@endsection
「Laravel 5.8 Bladeテンプレート」によると
@endsection
ディレクティブはセクションを定義するだけに対し、(以下略)
とあり、単純に@section
を閉じるだけの機能しか持たない。使い方としては@show
でも述べたように「子テンプレート」や「継承レイアウト」で@endsection
を使用することが多くなる。
@stop
は「Bladeでコンテンツの挿入を開始する」によると
@endsection
@stop
のエイリアスです
とあるように、@endsection
と同じ機能を持つ。
##@append
「Bladeでコンテンツの挿入を開始する」によると
@append
レンダリングを停止してセクションを追加する
とあるが、いまいちピンとこないので「Laravel 5.5 Blade @appendの使い方」を参考にいくつか例をあげつつ使用方法を検証する。
###例 append-1
@extends('layouts.layout')
<p>例1</p>
@section('hoge')
@show
@section('hoge')
@parent
hoge
@endsection
@section('hoge')
<br/>
fuga
@append
####結果
<body>
<p>例1</p>
hoge<br/>fuga
</body>
つまりは先の@section
に内容を追記できる。この機能と条件分岐を使用することで表示結果を変えるという使い方ができそう。
###例 append-2
@extends('layouts.layout')
<p>例2</p>
@section('hoge')
@show
@section('hoge')
@parent
メッセージは
@endsection
@if($msg !='')
@section('hoge')
<br/>{{$msg}}
@append
@else
@section('hoge')
<br/>ありません!
@append
@endif
####結果
$msgが空のとき
<body>
<p>例1</p>
メッセージは<br/>ありません!
</body>
$msgが'hoge'のとき
<body>
<p>例1</p>
メッセージは<br/>hoge
</body>
##@overwrite
「Bladeでコンテンツの挿入を開始する」によると
@overwrite
コンテンツの挿入を停止してセクションを上書きする.
とある。例をあげて挙動を確認する。
###例 overwrite-1
@extends('layouts.layout')
<p>例1</p>
@section('hoge')
@show
@section('hoge')
@parent
hoge
@endsection
@section('hoge')
@parent
<br/>fuga
@overwrite
####結果
<body>
<p>例1</p>
<br/>fuga
</body>
@append
と同様に条件分岐と組み合わせてなんかできそう。
###例 overwrite-2
@extends('layouts.layout')
<p>例2</p>
@section('hoge')
@show
@section('hoge')
@parent
メッセージは
@endsection
@if($msg !='')
@section('hoge')
<br/>{{$msg}}
@append
@else
@section('hoge')
@parent
からっぽ!
@append
@endif
####結果
$msgが空のとき
<body>
<p>例1</p>
からっぽ!
</body>
$msgが'hoge'のとき
<body>
<p>例1</p>
メッセージは<br/>hoge
</body>
#参考
- Laravel 5.8 Bladeテンプレート
- Bladeでコンテンツの挿入を開始する
- Laravel Blade で@include @yield @section を使いこなそう
- Laravel 5.5 Blade @appendの使い方
ありがとうございます。