5
6

More than 5 years have passed since last update.

@section ディレクティブの閉じ方

Posted at

@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を使用した場合
おそらく、例中で最も思った結果になる方法だと思う。

親 layout.blade.php
@extends('layouts.layout')
<p>例1</p>
@section('hoge')
@show
子 index.blade.php
@section('hoge')
@parent
hoge
@endsection

結果

<body>
<p>例1</p>
hoge
</body>

親の@section@showを引き継ぎつつ子の@section@endsectionに置き換えている。


例 show-2

親テンプレートに@showを使用しただけの場合
これは失敗例。@parentを忘れた場合。

親 layout.blade.php
@extends('layouts.layout')
<p>例2</p>
@section('hoge')
@show
子 index.blade.php
@section('hoge')
hoge
@endsection

結果

<body>
<p>例2</p>
</body>

親の@section@showが子の@section@endsectionに置き換えているため、レンダリングされないまま出力された。


例 show-3

失敗例?その2。
子に@showを、親に@endsection付けた場合

親 layout.blade.php
<p>例3</p>
@section('hoge')
@endsection
子 index.blade.php
@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

親 layout.blade.php
@extends('layouts.layout')
<p>例1</p>
@section('hoge')
@show
子 index.blade.php
@section('hoge')
    @parent
    hoge
@endsection

@section('hoge')
    <br/>
    fuga
@append

結果

<body>
<p>例1</p>
hoge<br/>fuga
</body>

つまりは先の@sectionに内容を追記できる。この機能と条件分岐を使用することで表示結果を変えるという使い方ができそう。


例 append-2

親 layout.blade.php
@extends('layouts.layout')
<p>例2</p>
@section('hoge')
@show
子 index.blade.php
@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

親 layout.blade.php
@extends('layouts.layout')
<p>例1</p>
@section('hoge')
@show
子 index.blade.php
@section('hoge')
    @parent
    hoge
@endsection

@section('hoge')
    @parent
    <br/>fuga
@overwrite

結果

<body>
<p>例1</p>
    <br/>fuga
</body>

@appendと同様に条件分岐と組み合わせてなんかできそう。


例 overwrite-2

親 layout.blade.php
@extends('layouts.layout')
<p>例2</p>
@section('hoge')
@show
子 index.blade.php
@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>

参考

ありがとうございます。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6