Les 3 · Module 1 · Laravel-basis
Blade-templates en componenten
Bouw de layout van de kassa met Blade: echo's, @if en @foreach, een gedeelde layout met componenten en slots, en herbruikbare formuliervelden.
🎯 Na deze les kun je
- Blade-directives voor voorwaarden en lussen gebruiken
- een layout maken als component met slots
- anonieme en klasse-componenten met props schrijven
- uitleggen wanneer {!! !!} gevaarlijk is
Elke pagina van de kassa heeft dezelfde kop, hetzelfde menu en dezelfde voet. Kopiëren en plakken werkt tot je het
menu wilt aanpassen. Blade is de template-taal van Laravel: gewone HTML met een paar @-directives en
componenten om stukken te hergebruiken.
Echo's en directives
<p>Hallo {{ $naam }}</p> {{-- ge-escapet --}}
<p>{{ $omschrijving ?? 'Geen omschrijving' }}</p>
@if ($regels->isEmpty())
<p>De bon is leeg.</p>
@elseif ($regels->count() > 10)
<p>Grote bestelling!</p>
@endif
@foreach ($regels as $regel)
<li @class(['duur' => $regel['prijs'] > 5])>{{ $regel['naam'] }}</li>
@endforeach
@forelse ($producten as $p)
<li>{{ $p['naam'] }}</li>
@empty
<li>Nog geen producten.</li>
@endforelse
In een @foreach heb je $loop: $loop->iteration (vanaf 1), $loop->first, $loop->last, $loop->count.
{{-- … --}} is commentaar dat niet in de HTML komt.
Voorspel eerst: $naam is <b>Sam</b>. Wat zie je bij {{ $naam }} en wat bij {!! $naam !!}?
Uitkomst
{{ $naam }} toont letterlijk <b>Sam</b> (de tekens zijn ge-escapet). {!! $naam !!} toont Sam vetgedrukt: de HTML
wordt uitgevoerd. Komt $naam van een gebruiker, dan is {!! !!} een XSS-lek. Gebruik het alleen voor HTML die je zelf maakt.
Een layout als component
Maak resources/views/components/layout.blade.php:
<!doctype html>
<html lang="nl">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ $titel ?? 'Kassa' }} · kassa</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<nav>
<a href="{{ route('kassa.index') }}">Kassa</a>
<a href="{{ route('producten.index') }}">Producten</a>
</nav>
<main>{{ $slot }}</main>
</body>
</html>
Een pagina gebruikt hem zo:
<x-layout titel="Bon">
<h1>Bon</h1>
...
</x-layout>
Alles tussen <x-layout> en </x-layout> komt in $slot. Een attribuut als titel="Bon" wordt de variabele $titel.
@vite laadt CSS en JavaScript via Vite (npm install && npm run dev); zonder Node kun je ook gewoon
<link rel="stylesheet" href="{{ asset('css/kassa.css') }}"> gebruiken met een bestand in public/css/.
Benoemde slots
{{-- components/kaart.blade.php --}}
<section class="kaart">
<header>{{ $kop }}</header>
{{ $slot }}
@isset($voet)<footer>{{ $voet }}</footer>@endisset
</section>
<x-kaart>
<x-slot:kop>Totaal vandaag</x-slot:kop>
<p>€ 312,40</p>
<x-slot:voet>Bijgewerkt om 15:00</x-slot:voet>
</x-kaart>
Componenten met props
Een formulierveld komt overal terug. resources/views/components/veld.blade.php:
@props(['naam', 'label', 'type' => 'text'])
<label>
{{ $label }}
<input type="{{ $type }}" name="{{ $naam }}" value="{{ old($naam) }}" {{ $attributes }}>
@error($naam)<span class="fout">{{ $message }}</span>@enderror
</label>
<x-veld naam="prijs" label="Prijs" inputmode="decimal" required />
@props noemt de verwachte eigenschappen met standaardwaarden; alles wat overblijft (inputmode, required) staat in
$attributes. old() en @error gebruik je in les 5.
Wil je logica in een component, maak dan een klasse: php artisan make:component Bedrag geeft
app/View/Components/Bedrag.php met een render()-methode.
Typische fouten
Undefined variable $titel: geef een standaard met??of zet hem in@props.- Component niet gevonden: het bestand moet in
resources/views/components/staan;<x-formulier.veld>zoektcomponents/formulier/veld.blade.php. - Oude weergave na wijziging: Blade cachet gecompileerde views;
php artisan view:clear.
Oefenen
- Maak de component
layouten laat alle bestaande views hem gebruiken. - Maak een component
<x-bedrag :waarde="2.8" />die€ 2,80toont. - Toon de productlijst met
@forelseen markeer producten boven € 4 met@class. - Maak de component
kaartmet een benoemd slotkopen gebruik hem op de startpagina.
Modelantwoord oefening 1
Elke view begint met <x-layout titel="…"> en eindigt met </x-layout>. Er staat geen <html> of <head> meer in.
Modelantwoord oefening 2
{{-- components/bedrag.blade.php --}}
@props(['waarde'])
<span class="bedrag">€ {{ number_format($waarde, 2, ',', '.') }}</span>
De dubbele punt in :waarde="2.8" betekent: dit is een PHP-expressie, geen tekst.
Modelantwoord oefening 3
@forelse ($producten as $p)
<li @class(['duur' => $p['prijs'] > 4])>{{ $p['naam'] }} <x-bedrag :waarde="$p['prijs']" /></li>
@empty
<li>Nog geen producten.</li>
@endforelse
Modelantwoord oefening 4
Zie het voorbeeld bij Benoemde slots. Zonder voet laat @isset de footer weg.
Lokaal oefenen
Geen live lab. Bekijk de bron van je pagina (Ctrl+U) om te zien welke HTML Blade maakt.
Samenvatting
{{ }}escapet,{!! !!}niet;@if,@foreach,@forelse,@classsturen.- Een layout is een component met
$slot; benoemde slots en props maken componenten flexibel. - Volgende les: wat Laravel doet tussen verzoek en antwoord.