Laravel再入門(6)

認証機能を追加したところ、TODO機能が動作しなくなりました。
AI(Google AI Studio)の出番です。

ユーザー認証追加後にTODOアプリの機能を追加したところ、以下のエラーが表示されました。
修正方法を教えてください。

resources/views/layouts/app.blade.php
Undefined variable $slot

回答。ちょっと長いです。

エラーメッセージ Undefined variable $slot は、Bladeテンプレートの @yield('content') の代わりに、{{ $slot }} が使われているにもかかわらず、$slot 変数が定義されていない場合に発生します。これは、@yield('content') を利用するレイアウトを {{ $slot }} を利用するコンポーネントベースのレイアウトに移行する際に発生しやすい問題です。

laravel/breeze や laravel/jetstream のようなパッケージは、コンポーネントベースのレイアウトをデフォルトで使用しますが、laravel/ui は @yield を使用したレイアウトです。

修正方法

エラーを修正するには、以下のいずれかの方法を検討してください。

1. @yield('content') を使用したレイアウトに戻す

resources/views/layouts/app.blade.php を @yield を使用するように変更します。

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Fonts -->
    <link rel="preconnect" href="https://fonts.bunny.net">
    <link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />

    <!-- Scripts -->
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body class="font-sans antialiased">
    <div class="min-h-screen bg-gray-100">
        @include('layouts.navigation')

        <!-- Page Heading -->
        @if (isset($header))
            <header class="bg-white shadow">
                <div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
                    {{ $header }}
                </div>
            </header>
        @endif

        <!-- Page Content -->
        <main>
            @yield('content') <!-- ここを変更 -->
        </main>
    </div>
</body>
</html>
そして、それぞれのビューで @section('content') を使い、コンテンツを挿入するようにします。

例: resources/views/todos/index.blade.php

@extends('layouts.app')

@section('content')
    <div class="py-12">
        <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
            <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                <div class="p-6 text-gray-900">
                    <!-- TODO リストの内容 -->
                    <!-- ここにTODOリストのコードを記述 -->
                </div>
            </div>
        </div>
    </div>
@endsection
この方法が適している場合:

laravel/ui を使っていたプロジェクトをベースにしている場合

コンポーネントベースのレイアウトに移行するのが面倒な場合

2. コンポーネントベースのレイアウトに移行する (推奨)

laravel/breeze や laravel/jetstream はコンポーネントベースのレイアウトを使用します。$slot は、コンポーネントに渡されるコンテンツを表す変数です。resources/views/components/ ディレクトリにある layout.blade.php や guest-layout.blade.php がそれにあたります。

もし、コンポーネントベースのレイアウトを使用しているのであれば、それぞれの Blade ビューで、x- で始まるコンポーネントタグを使ってコンテンツを挿入するように変更する必要があります。

例: resources/views/todos/index.blade.php
<x-app-layout> <!-- ここを変更 -->
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            TODO List
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
            <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                <div class="p-6 text-gray-900">
                    <!-- TODO リストの内容 -->
                    <!-- ここにTODOリストのコードを記述 -->
                </div>
            </div>
        </div>
    </div>
</x-app-layout>
この例では、x-app-layout というコンポーネントを使用し、header という名前付きスロットと、メインコンテンツを挿入しています。x-app-layout コンポーネントの中で $slot を使い、コンテンツを表示します。

この方法が適している場合:

laravel/breeze や laravel/jetstream を使っている場合

モダンなコンポーネントベースの開発に移行したい場合

3. 具体的な状況に合わせて修正

どちらの方法を選ぶかは、プロジェクトの状況や、あなたが使用しているパッケージによって異なります。エラーが発生している resources/views/layouts/app.blade.php の内容と、resources/views/todos/index.blade.php などのビューの内容を詳しく教えていただければ、より具体的なアドバイスができます。

補足:
laravel/breeze をインストールした場合は、resources/views/layouts/app.blade.php の内容が $slot を使うコンポーネントベースのレイアウトになっているはずです。

laravel/ui をインストールした場合は、@yield を使うレイアウトになっているはずです。

TODO アプリの機能を追加する際に、laravel/breeze などのパッケージが提供するコンポーネントレイアウトに変更した場合に、このエラーが発生する可能性があります。

修正後、キャッシュをクリアするために、以下のコマンドを実行することをおすすめします。

php artisan cache:clear
php artisan view:clear

まとめると、Laravel11でbreezeを使った認証を使う場合、テンプレートファイルが更新されます。10までと同じように使うか、11から採用されたコンポーネントベースのUIにするか選択する必要があります。

表示できました。
Laravel11は変更が多いので再入門に適していないバージョンだったかもしれません。。。

更新版TODOリスト

いいなと思ったら応援しよう!