トップページ
Laravel学習サイトLaravelやるばい

目次

テンプレートに共通のレイアウトを使う方法

今回はテンプレートに共通のレイアウトを使う方法を解説します。

ECサイトを作る記事のコードで解説します。

商品一覧ページのコードは下記でした。

<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <title>商品一覧</title>
    </head>
    <body>
        <div class="item-container">
            <div class="link-wrap">
                @if (Auth::id() == 1)
                    <a href="{{ route('shop.create') }}">商品作成</a>
                @endif
                <a href="{{ route('shop.mycart') }}">カート</a>
            </div>
            <h1>商品一覧</h1>
            @if(session('message'))
                <div class="flash">
                    {{ session('message') }}
                </div>
            @endif
            <div class="item-wrap">
                @forelse($items as $item)
                    <div class="item">
                        <h2>{{ $item->name }}</h2>
                        <img src="{{ asset('storage/images/' . $item->image) }}" alt="">
                        <p>{{ $item->detail }}</p>
                        @if (Auth::id() == 1)
                            <form method="post" action="{{ route('shop.delete', ['stock' => $item->id]) }}">
                                @csrf
                                @method('DELETE')
                                <button class="delete-button" onClick="return confirm('本当に削除しますか?');">削除</button>
                            </form>
                            <a class="item-edit" href="{{ route('shop.edit', ['stock' => $item->id]) }}">編集</a>
                        @endif
                        <form action="{{ route('shop.addmycart') }}" method="post">
                            @csrf
                            <input type="hidden" name="stock_id" value="{{ $item->id }}">
                            <input type="submit" value="カートに入れる">
                        </form>
                    </div>
                @empty
                    <p>登録商品がまだありません。</p>
                @endforelse
            </div>
        </div>
    </body>
</html>

下記の部分ですがどのページを表示するテンプレートも同じ記述になっています。

<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <title>商品一覧</title>
    </head>
    <body>

こういう場合は共通のテンプレートを作って使いまわした方がメンテナンス性が高まります。

だからテンプレートにしましょう。


共通テンプレートの作成

「Laravelのプロジェクト > resources > views > components」の下にテンプレートを作成します。

名称を「layout.blade.php」とします。

そこに共通化したいテンプレートを記述します。

<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <title>{{ $title }}</title>
    </head>
    <body>

titleタグの中身ですが共通化に対応する為に「{{ $title }}」に変更しています。


コントローラーの記述

layout.blade.phpに記述している{{ $title }}にコントローラーから値を渡さないとエラーになるので下記の記述をします。

public function index(Stock $stock) {
    view()->share('title', '商品一覧');

    $items = $stock->itemIndex();

    return view('shop.index', compact('items'));
}

「view()->share('title', '商品一覧')」の部分です。

「title」が「{{ $title }}」に対応しています。

「商品一覧」がtitleの値です。


共通テンプレートの利用

商品一覧ページのコードを下記に変更します。

<x-layout />
        <div class="item-container">
            <div class="link-wrap">
                @if (Auth::id() == 1)
                    <a href="{{ route('shop.create') }}">商品作成</a>
                @endif
                <a href="{{ route('shop.mycart') }}">カート</a>
            </div>
            <h1>商品一覧</h1>
            @if(session('message'))
                <div class="flash">
                    {{ session('message') }}
                </div>
            @endif
            <div class="item-wrap">
                @forelse($items as $item)
                    <div class="item">
                        <h2>{{ $item->name }}</h2>
                        <img src="{{ asset('storage/images/' . $item->image) }}" alt="">
                        <p>{{ $item->detail }}</p>
                        @if (Auth::id() == 1)
                            <form method="post" action="{{ route('shop.delete', ['stock' => $item->id]) }}">
                                @csrf
                                @method('DELETE')
                                <button class="delete-button" onClick="return confirm('本当に削除しますか?');">削除</button>
                            </form>
                            <a class="item-edit" href="{{ route('shop.edit', ['stock' => $item->id]) }}">編集</a>
                        @endif
                        <form action="{{ route('shop.addmycart') }}" method="post">
                            @csrf
                            <input type="hidden" name="stock_id" value="{{ $item->id }}">
                            <input type="submit" value="カートに入れる">
                        </form>
                    </div>
                @empty
                    <p>登録商品がまだありません。</p>
                @endforelse
            </div>
        </div>
    </body>
</html>

共通化した部分が「<x-layout />」です。

layoutは共通のテンプレート名です。

layout.blade.phpだったのでx-layoutにしています。

これでテンプレートの共通化が完成です。



戻る