ラボ > Laravel、Lumen:views関連

Laravel ビューでテンプレートを使う

ヘッダとかフッタとか共通なのでテンプレートにする

作成日:2019-03-26, 更新日:2023-07-03

基本

・「@yield()」を使う
・「@yield(〇〇)」と「@section(〇〇)」を合わせる
・「@section(〇〇)」で設定した値が「@yield(〇〇)」に入る
・「@yield(〇〇)」に対応する「@section(〇〇)」が無ければ空白
・「@section(〇〇, 〇〇〇)」はHTMLは使えない
・「@section(〇〇)〇〇〇@endsection」はHTMLは使える
・「{{-- 〇〇〇 --}}」はコメント
・「@extends()」は継承(各ビューはベースになるテンプレートを継承させる)
・「@include()」は読み込み

▼使うビューたち
・ベースにするビュー(テンプレート)
・各ビュー

▼ベースにするビュー(テンプレート):resources\views\layout\base.blade.php

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>@yield('title')</title>
  </head>
  <body>
    @yield('h1')
    @yield('contents')
  </body>
</html>

▼各ビュー

@extends('layout.base')

@section('title', 'hello')
@section('h1', '丸ごとシマウマ')
{{-- コメント。コメント。コメント。 --}}

@section('contents')
  <p>うはははは</p>
@endsection

共通テンプレートを組み込みたい

メニューやフッタなどを組み込む

・各ビューで組み込みたいビューを「@include(〇〇〇)」する
・「@include(〇〇〇)」している先で「@section(〇〇〇)」があってもOK。

▼使うファイル
・前述の「resources\views\layout\base.blade.php」「resources\views\layout\base.blade.php」
・新規で「resources\views\layout\navi.blade.php」

▼ベースにするビュー(テンプレート):resources\views\layout\base.blade.php

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>@yield('title')</title>
  </head>
  <body>
    @yield('navi')
    @yield('h1')
    @yield('contents')
  </body>
</html>

▼組み込むビュー(テンプレート):resources\views\layout\navi.blade.php

@section('navi')
  <div>共通のナビメニュー</div>
  @yield('pageJs')
@endsection

▼各ビュー

@extends('layout.base')

{{-- ▼layout.base --}}
@section('title', 'hello')
@section('h1', '丸ごとシマウマ')

{{-- ▼layout.navi --}}
@section('pageJs')
  <script src="/js/page.js"></script>
@endsection
@include('layout.navi')

@componentと$slot

いくつかサイトを見ても意味が分からん。
そのままコピペしてもエラーしか出ないサイトが多すぎる。

他のサイトを見ているとアラート表示を使うときに@componentと$slotを使っているみたい。

▼アラートのビュー:resources\views\common\alert.blade.php

{{ $slot }}

▼各ビュー

@component('common.alert')
  コンポーネントのテスト本文
@endcomponent

※「common\alert.blade.php」なので「@component('common.alert')」

別の値を渡す

▼アラートのビュー:resources\views\common\alert.blade.php

{{ $title }}
{{ $slot }}

▼各ビュー

@component('common.alert')
  @slot('title')
    コンポーネントのテストタイトル
  @endslot
  コンポーネントのテスト本文
@endcomponent

※「@slot()」で囲まれていないトコが「$slot」になる。

メモ:出力されるHTMLについて

そのまま「@component()」を使ったら希望していないトコに出力された。

▼ベースになるテンプレート

<html>
  〇〇〇
</html>

▼$slotのビュー

{{ $slot }}

▼各ビュー

@extends(〇〇〇)
@component(〇〇〇)
  丸ごとシマウマ
@endcomponent

▼出来上がるHTML

丸ごとシマウマ
<html>
  〇〇〇
</html>

▼希望していたHTML

<html>
  丸ごとシマウマ
  〇〇〇
</html>

@yield()との組み合わせ

出力したい場所を@yield()で決める。
→もっとスマートなやり方があるハズ。

▼ベースになるテンプレート

<html>
  @yield('hoge')
  〇〇〇
</html>

▼$slotのビュー

{{ $slot }}

▼各ビュー

@extends(〇〇〇)
@section('hoge')
  @component(〇〇〇)
    丸ごとシマウマ
  @endcomponent
@endsection

▼出来上がるHTML

<html>
  丸ごとシマウマ
  〇〇〇
</html>

めも

以下、必要な部分だけ抜き出し。

ベーステンプレートの指定:@extends()

「@extends()」で使いたいベースになるテンプレートを指定。

▼ベースになるテンプレート

<html>
  <head>
  </head>
  <body>
  </body>
</html>

▼各ビュー

@extends(ベースになるテンプレートを指定)

▼出来上がるHTML

<html>
  <head>
  </head>
  <body>
  </body>
</html>

ベースになるテンプレートの指定方法

・「〇〇〇.blade.php」の「〇〇〇」を使う
・「resources\views」の下にフォルダを作っているなら「.」で区切る

PATH 指定方法
resources\views\base.blade.php @extends('base')
resources\views\common\header.blade.php @extends('common.header')

値の表示:@yield()と@section()

「@yield()」を「@section()」で指定した値に置き換える

▼基本
・「@section()」の第2引数で指定
・「@section()」と「@endsection」で囲む

▼ベースになるテンプレート

@yield('hoge')

「@section()」の第2引数で指定:HTMLタグを文字として表示

「@section()」の第2引数を使う

▼各ビュー

@section('hoge', '<b>丸ごとシマウマ</b>')

▼出来上がるHTML

<b>丸ごとシマウマ</b>

※「<b>」が文字列として扱われる

「@section()」と「@endsection」で囲む:HTMLタグをHTMLタグとして表示

「@section()」と「@endsection」で囲む

▼各ビュー

@section('hoge')
  <b>丸ごとシマウマ</b>
@endsection

▼出来上がるHTML

丸ごとシマウマ

※「<b>」がHTMLタグとして扱われる

ベーステンプレートに別のテンプレートを差し込む:@include()

全体のベーステンプレートにとは別にヘッダメニューを差し込みたい

例えば・・・
・「カテゴリーA」に属する各ページと「カテゴリーB」に属する各ページでヘッダメニューを差し替えたい

▼ベースになるテンプレート

<html>
  <head>
  </head>
  <body>
    @yield('header')
  </body>
</html>

▼「カテゴリーA」用のヘッダメニュー

@section('header')
  <div>「カテゴリーA」用のヘッダメニュー</div>
@endsection

▼「カテゴリーB」用のヘッダメニュー

@section('header')
  <div>「カテゴリーB」用のヘッダメニュー</div>
@endsection

▼「カテゴリーA」に属する各ビュー

@extends(ベースになるテンプレートを指定)
@include(「カテゴリーA」用のヘッダメニューを指定)

▼「カテゴリーB」に属する各ビュー

@extends(ベースになるテンプレートを指定)
@include(「カテゴリーB」用のヘッダメニューを指定)

▼「カテゴリーA」に属する各ビューで出来上がるHTML

<html>
  <head>
  </head>
  <body>
    <div>「カテゴリーA」用のヘッダメニュー</div>
  </body>
</html>

▼「カテゴリーB」に属する各ビューで出来上がるHTML

<html>
  <head>
  </head>
  <body>
    <div>「カテゴリーB」用のヘッダメニュー</div>
  </body>
</html>

差し込むテンプレートに値を表示

「@yield()」と「@section()」を使う

▼「カテゴリーA」用のヘッダメニュー

@section('header')
  <div>「カテゴリーA」用のヘッダメニュー</div>
  @yield('hoge')
@endsection

▼「カテゴリーA」に属する各ビュー

@extends(ベースになるテンプレートを指定)
@include(「カテゴリーA」用のヘッダメニューを指定)

@section('hoge', '丸ごとシマウマ')

▼「カテゴリーA」に属する各ビューで出来上がるHTML

<html>
  <head>
  </head>
  <body>
    <div>「カテゴリーA」用のヘッダメニュー</div>
    丸ごとシマウマ
  </body>
</html>

値の追加:@section()~@show、@parent

「@yield()」と「@section()」で置き換えだが
「@section()~@show」と「@parent」で追加が可能

▼ベースになるテンプレート

@section('sub')
  <div>abc</div>
@show

▼各ビュー

@section('sub')
  @parent
  <div>123</div>
@endsection

▼出来上がるHTML

<div>abc</div>
<div>123</div>

@parentが無いときの結果

@section('sub')を置き換える→結果的には「@yield()」と「@section()」の組合せと同じっぽい。

▼各ビュー

@section('sub')
  <div>123</div>
@endsection

▼出来上がるHTML

<div>123</div>

関連項目