Laravel Bladeテンプレート入門|@extends・@yield・@section・@include・@pushを実例で復習
LaravelでWebアプリケーションを作り始めると、ルーティングやコントローラだけでなく、Bladeテンプレートという仕組みを理解することが重要になってきます。
最初のころは、@extends、@yield、@sectionといった記号が並んでいるだけで、「これって何が親で、何が子なんだ?」と少し混乱しました。
旅行に例えるなら、Bladeのレイアウト継承は「ホテルの基本的な造りは同じだけど、泊まる部屋によって中身が変わる」ようなイメージです。
建物や受付、廊下は共通。でも部屋ごとの内容は違います。
今回はLaravelの開発環境を整えながら、Bladeテンプレート、レイアウト継承、ルーティング、Eloquentを復習する中で、特に重要だったBladeの基本を整理してみました。
Laravel Bladeテンプレートとは?
BladeはLaravelに用意されているテンプレートエンジンです。
Bladeのファイルは基本的に.blade.phpという拡張子を使い、通常はresources/viewsの中に配置します。
例えば、記事一覧ページなら次のようなファイル構成になります。
resources/
└── views/
├── layouts/
│ └── app.blade.php
├── posts/
│ └── index.blade.php
└── partials/
└── header.blade.php
Bladeの大きなメリットは、HTMLの共通部分を何度もコピーしなくて済むことです。
ヘッダーやフッター、ページ全体のレイアウトを一つにまとめておけば、各ページでは必要な部分だけを書くことができます。
Bladeでは、PHPのコードを使いながらHTMLを分かりやすく記述できるため、Laravelで画面を作るときに欠かせない存在です。
Laravel Bladeのレイアウト継承を理解する
Bladeを学習するときに、最初に覚えておきたいのがレイアウト継承です。
基本的な考え方はとてもシンプルです。
- 親テンプレートに「ここへ子ページの内容を入れる」という場所を作る
- 子テンプレートが親テンプレートを継承する
- 子ページが必要な部分を埋める
つまり、親テンプレートが「Webサイトの骨組み」で、子テンプレートが「各ページの中身」です。
Laravelの@extendsで親レイアウトを指定する
子ページでは、まず@extendsを使って親テンプレートを指定します。
@extends('layouts.app')
この場合、Laravelはresources/views/layouts/app.blade.phpを親レイアウトとして扱います。
例えば記事一覧ページなら、次のような形です。
@extends('layouts.app')
@section('title', '記事一覧')
@section('content')
<h1>記事一覧</h1>
@foreach ($posts as $post)
<p>{{ $post->title }}</p>
@endforeach
@endsection
ここで重要なのが、@extendsだけではページの中身は完成しないということです。
親レイアウト側に用意された「穴」に、@sectionを使って内容を入れていきます。
Laravelの@yieldと@sectionの関係
Laravel Bladeのレイアウト継承で特に重要なのが、@yieldと@sectionの組み合わせです。
親テンプレートに次のようなコードがあるとします。
<main>
@yield('content')
</main>
これは「contentという名前の場所に、子テンプレートの内容を表示してください」という意味です。
そして子テンプレートでは次のように書きます。
@section('content')
<h1>記事一覧</h1>
<p>ここに記事一覧を表示します。</p>
@endsection
イメージとしては、次のような関係です。
親テンプレート
↓
@yield('content')
↑
@section('content')
子ページの内容
@endsection
最初は少し記号が多く見えますが、「@yieldが受け皿、@sectionが中身」と覚えるとかなり分かりやすくなります。
Laravelの@yieldと@section ... @showの違い
ここは今回の復習で特に重要だったポイントです。
通常の@yieldは、子テンプレートから指定されたセクションを表示するための場所です。
@yield('content')
一方、親側でデフォルトの内容を用意しておきたい場合には、@section ... @showという書き方があります。
@section('footer')
<p>© MyApp</p>
@show
この場合、子ページがfooterセクションを定義しなければ、親側に書いたデフォルト内容が表示されます。
そして子ページ側で次のようにすると、親の内容を残しながら追加できます。
@section('footer')
@parent
<p>追加のフッター情報</p>
@endsection
Laravelの@parentは何のために使う?
@parentは、親セクションの内容を残したまま子側の内容を追加したいときに使います。
例えば親に次のコードがあるとします。
@section('footer')
<p>MyApp</p>
@show
子側で次のように書きます。
@section('footer')
@parent
<p>お問い合わせはこちら</p>
@endsection
すると、親側の「MyApp」を残しながら、子ページ独自の「お問い合わせはこちら」を追加できます。
「完全に置き換える」のか「親を残して追加する」のか。この違いを覚えておくと、Bladeのレイアウト設計がかなり楽になります。
Laravel Bladeの@pushと@stackでCSS・JavaScriptを管理する
Bladeを使って少し大きなWebアプリケーションを作るようになると、「このページだけJavaScriptを読み込みたい」という場面が出てきます。
そんなときに便利なのが、@pushと@stackです。
親レイアウトに次のような場所を用意します。
<head>
@stack('styles')
</head>
<body>
@yield('content')
@stack('scripts')
</body>
そして子ページ側から、必要なJavaScriptを追加します。
@push('scripts')
<script src="/js/posts.js"></script>
@endpush
この組み合わせは、親レイアウトに追加用の受け皿を作り、子ページから必要なCSSやJavaScriptを積み上げるという考え方です。
@sectionと@pushの使い分け
ざっくり覚えるなら、次のように整理すると分かりやすいです。
- @section:ページの主要なコンテンツを入れる
- @yield:親側でセクションの表示場所を作る
- @push:CSSやJavaScriptなどを追加する
- @stack:pushされた内容を表示する場所
例えば記事ページなら本文は@section('content')、記事ページ専用のJavaScriptなら@push('scripts')という具合です。
Laravel Bladeの@includeで共通部品を使い回す
Webサイトを作っていると、ヘッダーやアラート、ナビゲーションなど、何度も登場するHTMLがあります。
毎回コピー&ペーストしていたら、あとで修正するときに大変です。
そこで使えるのが@includeです。
例えば、次のように書くことができます。
@include('partials.alert', [
'type' => 'success',
'message' => '保存しました'
])
呼び出される側のpartials/alert.blade.phpには、例えば次のように記述します。
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>
共通パーツを別ファイルに分けておくことで、同じHTMLを何度も書かなくて済みます。
Laravel Bladeコンポーネントも覚えておきたい
さらにBladeにはコンポーネントという仕組みがあります。
例えばアラートをコンポーネント化すると、次のように書けます。
<x-alert type="success">
保存しました
</x-alert>
コンポーネント側では、例えば次のように定義できます。
@props(['type' => 'info'])
<div class="alert alert-{{ $type }}">
{{ $slot }}
</div>
ここで登場する$slotは、コンポーネントのタグで囲んだ部分を受け取る場所です。
例えば、
<x-alert type="success">
保存しました
</x-alert>
と書けば、「保存しました」の部分が$slotに入ります。
@includeとBladeコンポーネントの使い分け
どちらか一方しか使ってはいけないわけではありません。
個人的には、まず次のように考えると理解しやすいと思いました。
- 単純な共通HTMLを読み込みたい → @include
- 再利用するUI部品として整理したい → Bladeコンポーネント
- 属性やデータを受け取るUI部品を作りたい → コンポーネント
既存のLaravelプロジェクトでは@extendsを使ったレイアウト継承を見ることもあるので、まずは両方の仕組みを理解しておくことが大切です。
Laravel Bladeの{{ }}と{!! !!}の違い
Bladeでデータを画面に表示するとき、もう一つ注意したいのがエスケープです。
通常のデータ表示では、次のように書きます。
{{ $name }}
これはHTMLとして解釈されないようにエスケープして出力するため、ユーザー入力などを表示するときの基本的な書き方です。
一方、次のような書き方もあります。
{!! $html !!}
これはエスケープせずにHTMLを出力します。
便利ではありますが、ユーザーから受け取ったHTMLなどを無条件で表示すると、XSS(クロスサイト・スクリプティング)などのセキュリティ問題につながる可能性があります。
そのため、基本的には次のように覚えておきます。
- 通常の文字列 →
{{ }} - 信頼できるHTMLをそのまま出したい →
{!! !!}
Laravel Bladeでよく使う制御構文
BladeはHTMLを書きながら、PHPの条件分岐や繰り返し処理も組み込めます。
@ifで条件分岐
@if ($user->isAdmin())
<p>管理者です</p>
@elseif ($user->isEditor())
<p>編集者です</p>
@else
<p>一般ユーザーです</p>
@endif
@foreachで繰り返し処理
@foreach ($items as $item)
<p>{{ $item->name }}</p>
@endforeach
さらにBladeでは$loopを使って、現在のループ位置などを取得できます。
@foreach ($items as $item)
{{ $loop->index }}
{{ $item->name }}
@endforeach
@forelseでデータが空の場合も処理する
@forelse ($posts as $post)
<p>{{ $post->title }}</p>
@empty
<p>記事がありません。</p>
@endforelse
記事一覧などでは、データが0件の場合もあるので、@forelseは覚えておくと便利です。
@authと@guestでログイン状態を判定する
@auth
<p>ログイン中です</p>
@endauth
@guest
<p>ログインしてください</p>
@endguest
ログインユーザーとゲストユーザーで表示を切り替える場合によく使います。
Laravelのルーティング・コントローラ・Bladeのつながり
ここまでBladeの話をしてきましたが、実際のLaravel開発では、Bladeだけが単独で動いているわけではありません。
例えば記事一覧ページなら、次のような流れをイメージすると分かりやすいです。
ルーティング
↓
コントローラ
↓
Eloquent
↓
Blade
↓
HTMLとして表示
今回の例では、コントローラから次のようにしています。
public function index()
{
return view('posts.index', [
'posts' => Post::all()
]);
}
ここでPost::all()によって取得した記事データを、postsという名前でBladeへ渡しています。
そしてBlade側では、次のように表示します。
@foreach ($posts as $post)
<p>{{ $post->title }}</p>
@endforeach
最初は「ルーティング」「コントローラ」「Eloquent」「Blade」と覚えることが多く感じます。
でも実際に一つの画面を作ってみると、それぞれの役割が少しずつ見えてきます。
Laravel Bladeを復習して特に覚えておきたいポイント
今回の復習で、まず頭に残しておきたいのは次のポイントです。
- @extends:親レイアウトを継承する
- @yield:子ページの内容を表示する場所を作る
- @section:子ページから内容を渡す
- @show:セクションを定義し、その場で表示する
- @parent:親セクションの内容を残して追加する
- @push / @stack:CSSやJavaScriptなどを積み上げる
- @include:共通パーツを読み込む
- <x-...>:Bladeコンポーネントを利用する
- {{ }}:基本的なエスケープ付き出力
- {!! !!}:エスケープしないHTML出力
- @if / @foreach / @forelse:Blade内の条件分岐・繰り返し
Bladeレイアウト継承で迷ったときの考え方
Bladeのコードを見ていて混乱したら、まず「これは親か、子か?」を確認するのがおすすめです。
例えば、
resources/views/layouts/app.blade.php
に@yield('content')があれば、「ここに子ページのcontentが入るんだな」と考えます。
そして、
@extends('layouts.app')
@section('content')
...
@endsection
を見つけたら、「このページはlayouts.appを親として、そのcontent部分を埋めているんだな」と読み解けます。
この「親を見る → 穴を探す → 子を見る → 中身を確認する」という順番でコードを追っていくと、Bladeのファイルがかなり読みやすくなります。
Laravel Bladeを学習して感じたこと
Laravelを勉強していると、最初はディレクティブの名前を一つずつ暗記しようとしてしまいます。
でも、実際には暗記だけではなかなか身につきません。
例えば旅行中に初めて知らない街を歩くときも、道路の名前を全部覚えるより「駅はここ」「ホテルはこっち」「この道を曲がる」という位置関係を理解したほうが覚えやすいですよね。
Bladeもそれと少し似ています。
親レイアウトがあって、子ページがあり、そこにセクションを流し込む。
この全体像が分かれば、@extendsや@yield、@sectionの意味も自然につながってきます。
さらに@includeやBladeコンポーネントで部品を分け、@pushと@stackでページ固有のJavaScriptやCSSを管理する。
ここまで見えてくると、LaravelのBladeは単なる「HTMLを書くための記法」ではなく、Webページを整理して保守しやすくする仕組みなんだと実感できます。
まとめ|Laravel Bladeは「親・子・穴」の関係から覚える
今回のLaravel学習では、開発環境を整えながらルーティング、Blade、Eloquentなどを復習しました。
その中でもBladeは、今後Laravelで画面を作っていくうえで避けて通れない部分です。
特に最初は、次の関係を押さえておくと理解しやすくなります。
- 親レイアウト →
@extends - 表示する場所 →
@yield - 内容を入れる →
@section - 親の内容を残す →
@parent - 追加のCSS・JS →
@push/@stack - 共通パーツ →
@include - 再利用できるUI部品 → Bladeコンポーネント
Laravelを学習していると、次々に新しい機能が出てきて「全部覚えないといけないのかな」と焦ることがあります。
でも、実際の開発では必要になったときに調べながら使うことも多いです。
まずは一つの画面を作り、ルーティング → コントローラ → Eloquent → Blade → HTMLという流れを何度も経験する。
この繰り返しが、Laravelを「知っている」状態から「使える」状態へ進むための一歩だと思います。
今回のBlade復習を土台にして、次はルーティングやEloquent、マイグレーションまで実際の開発をイメージしながら整理していきたいと思います。







0 件のコメント:
コメントを投稿