Blade je jednoduchý šablonovací nástroj od Laravelu. Narozdíl od jiných populárních šablonovacích systémů Blade umožňuje
používat v pohledech i klasické PHP kódy. Ve výsledku se totiž Blade pohledy vždy zkompikují do čistého PHP a zakešují do té doby,
než jsou změněny. Blade pohledy mají koncovku .blade.php
a ve výchozím nastavení je najdeme v adresáři resources/views
.
Jednou z hlavních výhod při používání Blade jsou dědičnost šablon. Nejlepší to bude ukázat na příkladu. Drtivá většina stránek má layout vždy stejný, tedy například hlavičku, menu a patičku. Jediné co se mění, je samotný obsah. Jako první si tedy definujeme "hlavní" layout:
<!-- Layout ulozime do resources/views/layouts/app.blade.php -->
<html>
<head>
<title>Blog - @yield('title')</title>
</head>
<body>
@section('sidebar')
Toto je boční menu.
@show
<div class="container">
@yield('content')
</div>
</body>
</html>
Jak můžeme vidět, většina kódu je klasické HTML. Nicméně si všimněte direktiv @yield
a @section
. Direktiva @section
, jak
už název napovídá, definuje sekci kde bude obsah, zatímco direktiva @yield
slouží pro zobrazení obsahu dané sekce.
Tímto jsme si definovali základní layout a můžeme se vrhnout na další stránky, které budou tento layout dědit.
Když definujeme potomka, tak jako první použijeme direktivu @extends
pro specifikování z jakého layoutu chceme dědit.
Dále můžeme pomocí direktivy @section
vložit potřebný kód do obsahu rodiče. Kde se má tento obsah zobrazit jsme si definovali
v app.blade.php
direktivou @yield
. Může to znít trochu složitě, ale ukážeme si to na příkladě, kde se to dá lépe pochopit:
<!-- Ulozene v resources/views/child.blade.php -->
@extends('layouts.app')
@section('title', 'Název stránky')
@section('sidebar')
@parent
<p>Tato část se připojí k hlavnímu sidebaru.</p>
@endsection
@section('content')
<p>Toto je hlavní obsah.</p>
@endsection
V Blade se používá vazba @yield
a @section
. @yield
definuje, že zde bude dynamický obsah a @section
zajišťuje samotný
obsah sekce. To je příklad sekce title
a content
. Narozdíl od toho sekce sidebar
využívá direktivy @parent
, protože nechce
původní (rodičovský) kód přepsat, ale pouze ho doplnit k tomu, co už v sekci existuje.
Pokud bychom si chtěli stránku rovnou zobrazit, definujme si routu například /blade
:
Route::get('blade', function () {
return view('child');
});
Všimněte si, že jsme vrátili rovnou konečný Blade pohled, tedy child.blade.php
. Rodiče není potřeba nijak řešit, protože potomek se
sám stará o zavolání rodiče (direktiva @extends
).
Pokud nechceme mít pouze statické stránky, tak potřebujeme předávat do šablon i proměnné. To zajistíme tak, že při volání helperu
view()
jako druhý parametr (první parametr je název šablony) uvedeme pole s klíči a proměnnými:
Route::get('greeting', function () {
return view('welcome', ['name' => 'Hugo']);
});
V samotné šabloně pak proměnnou name
s hodnotou Hugo
zobrazíme pomocí složených závorek:
Ahoj, tady {{ $name }}
Je potřeba zmínit, že veškerý obsah ve složených závorkách prochází PHP funkcí htmlspecialchars()
, která zabraňuje XSS útokům.
Kromě toho nás nic nelimituje, jaký kód do složených závorek dáme. Můžeme dokonce i bez problémů volat nativní PHP funkce:
Aktuální UNIX časová známka je {{ time() }}.
Jak už jsem zmínil, veškerý obsah prochází kvůli ochraně funkcí htmlspecialchars()
. Pokud si jsme jistí jaký obsah se zde
bude vkládat a máme pro to dobrý důvod, můžeme tuto ochranu obejít použitím této syntaxe:
Ahoj, tady {!! $name !!}
Často se stává, že potřebujeme do šablony vložit do javascript proměnné data z backendu. Běžně bychom to museli udělat například takto:
<script>
var app = <?php echo json_encode($array); ?>;
</script>
Blade nám v tomto vychází vstříc a namísto toho můžeme využít direktivy @json
:
<script>
var app = @json($array);
</script>
To se může především hodit při definování hodnot ve Vue komponentách nebo v data-*
atributech:
<example-component :some-prop='@json($array)'></example-component>
Kromě dědičnosti a zobrazení dat umožňuje Blade také klasické operace s daty, jako jsou podmínky nebo cykly. Laravel se nám v tomto snaží jít co nejvíce naproti a umožňuje nám práci s nimi velmi jednoduše.
Direktivy pro podmínky jsou @if
, @elseif
, @else
a @endif
. Tyto direktivy fungují úplně stejné, jako bychom použili klasické PHP:
@if (count($records) === 1)
Pouze jeden záznam
@elseif (count($records) > 1)
Více záznamů
@else
Žádný záznam
@endif
Pro zjednodušení Blade také nabízí direktivu @unless
, která prakticky znamená if($variable === false)
:
@unless (Auth::check())
Nejste přihlášeni.
@endunless
Kromě těchto možností je také možné použít direktiv @isset
a @empty
:
@isset($records)
// $records je definovan a neni nulovy
@endisset
@empty($records)
// $records je "prazdny"
@endempty
Direktivy pro switch jsou @switch
, @case
, @break
, @default
a @endswitch
. Ty opět fungují stejně jako jejich klasické PHP protějšky:
@switch($i)
@case(1)
První nález
@break
@case(2)
Druhý nález
@break
@default
Nic se nenašlo
@endswitch
Pro procházení dat můžeme v Blade využít cykly, které běžně využíváme v PHP:
@for ($i = 0; $i < 10; $i++)
Aktuální hodnota je {{ $i }}
@endfor
@foreach ($users as $user)
<p>Tento uživatel má ID {{ $user->id }}</p>
@endforeach
@forelse ($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>Žádní uživatelé</p>
@endforelse
@while (true)
<p>Nekonečný cyklus.</p>
@endwhile
Kromě procházení dat můžeme také cyklus ukončit nebo přeskočit aktuální iteraci:
@foreach ($users as $user)
@if ($user->type == 1)
@continue
@endif
<li>{{ $user->name }}</li>
@if ($user->number == 5)
@break
@endif
@endforeach
Nebo použít zkrácenou verzi:
@foreach ($users as $user)
@continue($user->type == 1)
<li>{{ $user->name }}</li>
@break($user->number == 5)
@endforeach
Když probíhá cyklus, tak Laravel automaticky do iterace vkládá i proměnnou $loop
. Tato proměnná obsahuje užitečné informace
o aktuální iteraci:
@foreach ($users as $user)
@if ($loop->first)
Toto je první iterace a první uživatel je {{ $uesr->name }}
@endif
@if ($loop->last)
Toto je poslední iterace a poslední uživatel je {{ $uesr->name }}
@endif
<p>Uživatel má ID {{ $user->id }}</p>
@endforeach
Pokud bychom měli víceúrovňový cyklus, pak se můžeme dostat i k rodiči:
@foreach ($users as $user)
@foreach ($user->posts as $post)
@if ($loop->parent->first)
Toto je první iterace rodičovského cyklu
@endif
@endforeach
@endforeach
Kromě těchto metod proměnná $loop
obsahuje i jiné velmi užitečné metody:
Metoda | Popis |
---|---|
$loop->index |
Index aktuální iterace (začíná od 0) |
$loop->iteration |
Aktuální iterace (začíná od 1) |
$loop->remaining |
Zbývající iterace v cyklu |
$loop->count |
Celkový počet záznamů v poli, které se bude procházet |
$loop->first |
Jestli je tato iterace první v cyklu |
$loop->last |
Jestli je tato iterace poslední v cyklu |
$loop->even |
Jestli je tato iterace sudá v cyklu |
$loop->odd |
Jestli je tato iterace lichá v cyklu |
$loop->depth |
Hloubka aktuální iterace |
$loop->parent |
Rodičovská proměnná $loop pokud se jedná o zanořený cyklus |
Blade také umožňují definovat komentáře. Je důležité připomenout, že narozdíl od HTML komentářů, Blade komentáře se ve výsledném HTML nevrací, ve zdrojovém kódu je tak neuvidíte (namísto toho je jen prázdné místo):
{{-- Tento komentar nebude ve vyslednem vyrenderovanem HTML --}}
V některých situacích je potřeba vkládat PHP kód do šablon. K tomu můžeme využít direktivu @php
, která v šabloně vykoná
daný PHP kód:
@php
//
@endphp
Pokaždé když definujeme HTML formulář, měli bychom vkládat i skryté CSRF pole s tokenem, takže zabráníme CSRF útoku a požadavek
zároveň projde přes middleware (defaultně bez tohoto tokenu se požadavek nevykoná a vyhodí to chybu 419). Abychom nemuseli
toto skryté pole psát ručně, můžeme využít Blade direktivu @csrf
:
<form method="POST" action="/profile">
@csrf
...
</form>
Protože HTML formuláře nedokážou vytvářet požadavky typu PUT
, PATCH
nebo DELETE
, pro jejich odeslání je potřeba přidat
skryté pole _method
s HTTP typem požadavku. Blade direktiva @method
toto pole vytvoří za nás:
<form action="/foo/bar" method="POST">
@method('PUT')
...
</form>
Pokud bychom do šablony potřebovali vložit další šablonu, například pro separovaní vetší části kódu kvůli čitelnosti nebo znovupoužitelnosti,
můžeme použít direktivu @include
. Všechny proměnné, které jsou dostupné pro rodiče, budou také dostupné pro vkládnou šablonu:
<div>
@include('shared.errors')
<form>
<!-- Obsah formulare -->
</form>
</div>
Kromě toho, že jsou předávány všechny rodičovské proměnné, můžeme do přidávané šablony také přidat další extra data:
@include('view.name', ['some' => 'data'])
Pokud chcete vložit šablonu pouze na základě určité podmínky, pak to lze udělat jednoduše pomocí direktivy @includeWhen
:
@includeWhen($boolean, 'view.name', ['some' => 'data'])