Blade — Templates Laravel 12
Moteur de templates moderne avec composants et directives puissantes.
🏗️ Structure de base
Layout
{{-- resources/views/layouts/app.blade.php --}}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@yield('title', 'Mon App')</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<header>@include('partials.navigation')</header>
<main>@yield('content')</main>
<footer>@include('partials.footer')</footer>
</body>
</html>Héritage
@extends('layouts.app')
@section('title', 'Articles')
@section('content')
<h1>Tous les articles</h1>
@foreach($posts as $post)
<article>
<h2>{{ $post->title }}</h2>
<p>{{ Str::limit($post->content, 100) }}</p>
<a href="{{ route('posts.show', $post) }}">Lire plus</a>
</article>
@endforeach
@endsection🎯 Directives essentielles
Affichage
{{ $user->name }} <!-- Échappé automatique -->
{!! $post->html_content !!} <!-- Non échappé -->
{{ $user->name ?? 'Invité' }} <!-- Null coalescing -->
{{ __('messages.welcome') }} <!-- Traduction -->Conditions
@if($user->active)
<span class="badge success">Actif</span>
@elseif($user->pending)
<span class="badge warning">En attente</span>
@else
<span class="badge error">Inactif</span>
@endif
@unless($user->verified)
<p>Veuillez vérifier votre email</p>
@endunless
@isset($records)
<p>Records existent</p>
@endisset
@empty($records)
<p>Aucun enregistrement</p>
@endemptyBoucles
@foreach($users as $user)
<li>{{ $user->name }}</li>
@endforeach
@foreach($users as $index => $user)
<li>{{ $index + 1 }}. {{ $user->name }}</li>
@endforeach
@forelse($users as $user)
<li>{{ $user->name }}</li>
@empty
<li>Aucun utilisateur trouvé</li>
@endforelse
@while($count > 0)
<p>Compte: {{ $count }}</p>
<?php $count--; ?>
@endwhile
{{-- Break/continue --}}
@foreach($items as $item)
@if($item->skip)
@continue
@endif
<p>{{ $item->name }}</p>
@if($item->last)
@break
@endif
@endforeachSwitch
@switch($user->role)
@case('admin')
<p>Administrateur</p>
@break
@case('editor')
<p>Éditeur</p>
@break
@default
<p>Utilisateur</p>
@endswitch🎨 Composants Blade
Création
php artisan make:component Alert # inline
php artisan make:component Alert --view # avec vueComposant inline
<?php
// app/View/Components/Alert.php
namespace App\View\Components;
use Illuminate\View\Component;
use Illuminate\View\View;
class Alert extends Component
{
public function __construct(
public string $type = 'info',
public string $message = ''
) {}
public function render(): View
{
return view('components.alert');
}
}{{-- resources/views/components/alert.blade.php --}}
<div class="alert alert-{{ $type }}" {{ $attributes }}>
@if($message)
{{ $message }}
@else
{{ $slot }}
@endif
</div>Utilisation
<x-alert type="success" message="Opération réussie !" />
<x-alert type="warning">
<strong>Attention :</strong> Cette action est irréversible.
</x-alert>
<x-alert type="error" class="mb-4" id="error-alert">
Une erreur est survenue
</x-alert>
<x-alert :type="$alertType" :message="$alertMessage" />Composants anonymes
{{-- resources/views/components/card.blade.php --}}
@props(['title', 'footer'])
<div {{ $attributes->merge(['class' => 'card']) }}>
@if($title)
<div class="card-header">
<h3>{{ $title }}</h3>
</div>
@endif
<div class="card-body">
{{ $slot }}
</div>
@if($footer)
<div class="card-footer">
{{ $footer }}
</div>
@endif
</div><x-card title="Profil utilisateur" class="profile-card">
<p>Nom : {{ $user->name }}</p>
<p>Email : {{ $user->email }}</p>
<x-slot name="footer">
<button class="btn btn-primary">Modifier</button>
</x-slot>
</x-card>📝 Includes et Partials
@include('partials.navigation')
@include('partials.navigation', ['active' => 'home'])
@includeWhen($user->isAdmin(), 'partials.admin-menu')
@includeUnless($user->verified(), 'partials.verification-notice')
@include('partials.user-card', [
'user' => $user,
'showEmail' => true
])🎭 Directives personnalisées
// app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Blade;
public function boot(): void
{
Blade::directive('datetime', function ($expression) {
return "<?php echo ($expression)->format('d/m/Y H:i'); ?>";
});
Blade::if('env', function ($environment) {
return app()->environment($environment);
});
}<p>Créé le : @datetime($post->created_at)</p>
@env('local')
<div class="debug-bar">Mode développement</div>
@endenv🎨 Stacks
{{-- Layout --}}
@stack('styles')
@stack('scripts')
{{-- Vue --}}
@push('styles')
<link rel="stylesheet" href="/css/custom.css">
@endpush
@push('scripts')
<script src="/js/custom.js"></script>
@endpush
@prepend('scripts')
<script src="/js/priority.js"></script>
@endprepend📊 Formulaires
<form method="POST" action="{{ route('posts.store') }}">
@csrf
<div>
<label for="title">Titre</label>
<input type="text" id="title" name="title" value="{{ old('title') }}">
@error('title')
<span class="error">{{ $message }}</span>
@enderror
</div>
<div>
<label for="content">Contenu</label>
<textarea id="content" name="content">{{ old('content') }}</textarea>
@error('content')
<span class="error">{{ $message }}</span>
@enderror
</div>
<button type="submit">Créer</button>
</form>
{{-- Method spoofing --}}
<form action="{{ route('posts.update', $post) }}" method="POST">
@method('PUT')
@csrf
</form>
<form action="{{ route('posts.destroy', $post) }}" method="POST">
@method('DELETE')
@csrf
<button type="submit">Supprimer</button>
</form>🎯 Helpers
Auth
@auth
<p>Connecté en tant que {{ Auth::user()->name }}</p>
@endauth
@guest
<a href="{{ route('login') }}">Se connecter</a>
@endguest
@auth('admin')
<p>Admin connecté</p>
@endauthCSRF et Method
@csrf
{{ csrf_token() }}
@method('PUT')
{{ method_field('PUT') }}Errors
@error('email')
<span>{{ $message }}</span>
@enderror
{{ $errors->first('email') }}
@if($errors->any())
<div class="alert alert-danger">
<ul>
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endifFonctions utiles
<!-- URLs -->
{{ url('/path') }}
{{ route('posts.show', $post) }}
{{ action('PostController@show', $post) }}
{{ asset('css/app.css') }}
<!-- Strings -->
{{ Str::limit($text, 100) }}
{{ Str::slug($title) }}
{{ Str::ucfirst($name) }}
<!-- Dates -->
{{ $date->format('d/m/Y') }}
{{ $date->diffForHumans() }}
<!-- Arrays -->
{{ collect($items)->implode(', ') }}
{{ $items->count() }}
{{ $items->isEmpty() ? 'Vide' : 'Contient des éléments' }}🎨 Directives avancées
@once
@push('scripts')
<script src="/js/chart.js"></script>
@endpush
@endonce
@verbatim
<div class="example">
Ceci est un exemple avec des accolades {comme ceci}.
</div>
@endverbatim
@php
$total = 0;
foreach($items as $item) {
$total += $item->price;
}
@endphp
<p>Total : {{ $total }} €</p>PHP élégant dans des templates modernes