Layouts
Com organitzar les vistes amb layouts a Blade: layouts amb components i layouts clàssics.
Per què necessites layouts?#
A qualsevol aplicació web, la majoria de pàgines comparteixen elements comuns: el header, la navegació, el footer, els scripts i els estils CSS. Sense layouts, hauries de repetir tot aquest HTML a cada vista, cosa que faria el manteniment impossible. Els layouts permeten definir l'estructura comuna una sola vegada i reutilitzar-la a totes les pàgines.
Layouts amb components (recomanat)#
La manera recomanada de crear layouts a Laravel és amb components Blade. El layout és simplement un component que rep el contingut de cada pàgina a través del $slot:
{{-- resources/views/components/layout.blade.php --}}
<!DOCTYPE html>
<html lang="ca">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ $title ?? 'Laravel Andorra' }}</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
{{ $head ?? '' }}
</head>
<body class="min-h-screen bg-gray-100">
<nav class="bg-white shadow">
<div class="max-w-7xl mx-auto px-4">
<a href="/">Inici</a>
<a href="/articles">Articles</a>
@auth
<a href="/dashboard">Dashboard</a>
@endauth
</div>
</nav>
<main class="max-w-7xl mx-auto px-4 py-8">
{{ $slot }}
</main>
<footer class="bg-gray-800 text-white py-6">
<div class="max-w-7xl mx-auto px-4">
<p>© {{ date('Y') }} Laravel Andorra</p>
</div>
</footer>
{{ $scripts ?? '' }}
</body>
</html>Per utilitzar el layout, simplement envolta el contingut de la teva vista amb el component:
{{-- resources/views/home.blade.php --}}
<x-layout>
<x-slot:title>Pàgina d'inici</x-slot:title>
<h1 class="text-3xl font-bold mb-4">Benvingut!</h1>
<p>Aquesta és la pàgina principal de l'aplicació.</p>
</x-layout>El contingut entre les etiquetes <x-layout> va al $slot del layout. El slot amb nom title personalitza el títol de la pàgina. Si no el passes, s'utilitza el valor per defecte 'Laravel Andorra'.
Layouts amb slots opcionals#
L'exemple anterior inclou slots opcionals com $head i $scripts que permeten a cada pàgina afegir contingut addicional al <head> o abans del tancament del <body>:
<x-layout>
<x-slot:title>Dashboard</x-slot:title>
<x-slot:head>
<link rel="stylesheet" href="{{ asset('css/dashboard.css') }}">
</x-slot:head>
<h1>Dashboard</h1>
<div id="chart"></div>
<x-slot:scripts>
<script src="{{ asset('js/chart.js') }}"></script>
</x-slot:scripts>
</x-layout>Múltiples layouts#
Pots tenir diversos layouts per a parts diferents de l'aplicació. Per exemple, un layout per a la part pública, un per al panell d'administració i un per a les pàgines d'autenticació:
{{-- Pàgina pública --}}
<x-layout>
<h1>Benvingut</h1>
</x-layout>
{{-- Panell d'administració --}}
<x-admin-layout>
<h1>Dashboard</h1>
</x-admin-layout>
{{-- Pàgina de login --}}
<x-auth-layout>
<h1>Inicia sessió</h1>
</x-auth-layout>Layouts clàssics amb @extends#
L'enfocament clàssic utilitza les directives @extends, @section i @yield. Tot i que els layouts amb components són la manera recomanada, entendre el sistema clàssic és important perquè molts projectes existents l'utilitzen.
Primer, defineixes el layout amb @yield als llocs on cada pàgina posarà el seu contingut:
{{-- resources/views/layouts/app.blade.php --}}
<!DOCTYPE html>
<html lang="ca">
<head>
<meta charset="UTF-8">
<title>@yield('title', 'Laravel Andorra')</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
@yield('styles')
</head>
<body>
<nav>
@include('partials.nav')
</nav>
<main class="container">
@yield('content')
</main>
<footer>
@include('partials.footer')
</footer>
@yield('scripts')
</body>
</html>Després, les vistes filles utilitzen @extends per heretar el layout i @section per omplir els blocs:
{{-- resources/views/users/index.blade.php --}}
@extends('layouts.app')
@section('title', 'Llista d\'usuaris')
@section('content')
<h1>Usuaris</h1>
@forelse($users as $user)
<div class="card">
<h3>{{ $user->name }}</h3>
<p>{{ $user->email }}</p>
</div>
@empty
<p>No hi ha usuaris registrats.</p>
@endforelse
{{ $users->links() }}
@endsection
@section('scripts')
<script src="{{ asset('js/users.js') }}"></script>
@endsectionLa directiva @section amb un segon paràmetre (@section('title', 'Llista d\'usuaris')) estableix un valor curt. Per a blocs de contingut més llargs, utilitza @section amb @endsection.
@parent#
Si el layout defineix contingut per defecte a un bloc i la vista filla vol afegir-hi contingut en lloc de substituir-lo, pot fer servir @parent:
{{-- Layout --}}
@section('sidebar')
<nav>Navegació per defecte</nav>
@show
{{-- Vista filla --}}
@section('sidebar')
@parent
<nav>Navegació addicional</nav>
@endsectionLa directiva @parent insereix el contingut del layout al lloc on s'escriu, permetent estendre el bloc en lloc de sobreescriure'l completament.
Organitzar vistes#
A mesura que el projecte creix, és important organitzar les vistes en subdirectoris que reflecteixin l'estructura de l'aplicació:
resources/views/
├── components/
│ ├── layout.blade.php
│ ├── admin-layout.blade.php
│ ├── alert.blade.php
│ ├── button.blade.php
│ └── form/
│ ├── input.blade.php
│ └── select.blade.php
├── partials/
│ ├── nav.blade.php
│ └── footer.blade.php
├── users/
│ ├── index.blade.php
│ ├── show.blade.php
│ └── edit.blade.php
├── articles/
│ ├── index.blade.php
│ └── show.blade.php
└── home.blade.php
Els components van a components/, les vistes parcials reutilitzables a partials/, i les vistes de cada recurs en el seu propi directori. Per accedir a qualsevol vista, utilitza notació de punt: view('users.index') correspon a resources/views/users/index.blade.php.