Poznajemy Layout Inheritance w Laravelu, dzięki której nie będziemy musieli powtarzać sekcji head i body w naszych widokach. Do dzieła.

Zaczniemy od utworzenia nowego projektu w folderze htdocs:

composer create-project laravel/laravel layout-app

Potem albo robimy:

cd layout-app

Albo jeszcze lepiej – otwieramy za pomocą edytora (np. vscode) cały projekt.

W odpowiednim folderze robimy:

npm install

W folderze views robimy katalog layouts, w nim plik app.blade.php:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    @yield('content')
</body>
</html>

Teraz tworzymy (w views) plik welcome2.blade.php o takiej treści:

@extends('layouts.app')

@section('content')

 <h1>Hello World!</h1>

@endsection

Dokonujemy zmian w routes.php:

Route::get('/', function () {
    return view('welcome2');
});

Wykonujemy komendę:

php artisan serve

Sprawdzamy jak działa. Ok, pora ustawić CSS. Vite.config:

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/js/app.js'],
            refresh: true,
        }),
    ],
});

Zawartość app.js (w resources):

import './bootstrap';
import '../css/app.css';

Bootstrap to nie framework CSS btw tylko miejsce, gdzie mamy bootstraping assetów JS (jeżeli robiliśmy projekt „Własny framework MVC w PHP” powinniśmy wiedzieć, co to bootstrapping).

Ok, teraz dodajemy ten JS przez vite do layouta:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    @vite('resources/js/app.js')
</head>
<body>
    @yield('content')
</body>
</html>

Jeszcze coś zmieńmy w CSS (resources/app.css), aby widać było:

body {
    color:teal;
}

Jeżeli serwer nam działa to wychodzimy i wpisujemy komendy:

npm run build;
php artisan serve

Ok, teraz widać zmiany. Dodamy jeszcze możliwość ustawiania tytułu w layoucie:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@yield('title', 'Layout App')</title>
    @vite('resources/js/app.js')
</head>
<body>
    @yield('content')
</body>
</html>

I przykład użycia:

@extends('layouts.app')

@section('title', 'Index Page')
@section('content')

 <h1>Hello World!</h1>

@endsection

Możemy też pokombinować i takie coś ustawić w app.blade.php:

<title>Layout App - @yield('title')</title>

Teraz wszystkie tytuły mają prefix plus to, co wrzucą w w section title. Nic nie stoi na przeszkodzie, aby dodać tam wartość domyślną:

<title>Layout App - @yield('title', 'Main Page')</title>

Jeżeli chodzi o template inheritance layouts to jest jeszcze możliwość „superowania” sekcji z layoutów-rodziców:

 
<html>
    <head>
        <title>App Name - @yield('title')</title>
    </head>
    <body>
        @section('sidebar')
            This is the master sidebar.
        @show
 
        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

Tak wygląda użycie tego layoutu:

@extends('layouts.app')
 
@section('title', 'Page Title')
 
@section('sidebar')
    @parent
 
    <p>This is appended to the master sidebar.</p>
@endsection
 
@section('content')
    <p>This is my body content.</p>
@endsection

Mamy też layouty-blade komponenty, ale one nie wyglądają najciekawiej i generalnie nie wiem, czy są aż tak potrzebne. Poczytać o nich możemy w dokumentacji.

Więcej Laravela wkrótce!