Blade и шаблоны
Директивы, наследование шаблонов, компоненты, экранирование, формы.
Junior Что такое Blade? Как выводятся данные и в чём разница {{ }} и {!! !!}?
Blade — встроенный шаблонизатор Laravel. Шаблоны компилируются в чистый PHP и кэшируются (storage/framework/views), поэтому оверхед минимален.
{{ $name }} {{-- вывод с экранированием через htmlspecialchars (защита от XSS) --}}
{!! $html !!} {{-- вывод БЕЗ экранирования — только для доверенного HTML --}}
{{ $name ?? 'Гость' }} {{-- значение по умолчанию --}}
@{{ не blade }} {{-- экранирование самой директивы --}}
Комментарии {{-- ... --}} не попадают в итоговый HTML (в отличие от <!-- -->).
Проверка: {!! !!} с пользовательскими данными — типичная XSS-уязвимость; на собеседовании об этом спросят почти наверняка.
Junior Какие основные директивы Blade вы знаете?
Условия:
@if ($users->isEmpty()) ... @elseif (...) ... @else ... @endif
@unless ($user->active) ... @endunless
@isset($var) ... @endisset
@empty($items) ... @endempty
@auth ... @endauth @guest ... @endguest
@switch($role) @case('admin') ... @break @default ... @endswitch
Циклы:
@foreach ($posts as $post) ... @endforeach
@forelse ($posts as $post) ... @empty ... @endforelse
@for / @while
Внутри циклов доступен объект $loop: $loop->first, $loop->last, $loop->iteration, $loop->even.
Прочее:
@include('partials.nav', ['active' => 'home'])
@csrf @method('PUT')
@php ... @endphp
@verbatim ... @endverbatim {{-- вывод без обработки Blade (для Vue/JS) --}}
Кастомные директивы: Blade::directive('money', fn ($e) => "...").
Junior Как работает наследование шаблонов: @extends, @section, @yield?
Мастер-шаблон layouts/app.blade.php:
<html>
<head><title>@yield('title', 'По умолчанию')</title></head>
<body>
@yield('content')
</body>
</html>
Дочерний шаблон:
@extends('layouts.app')
@section('title', 'Главная')
@section('content')
<h1>Привет</h1>
@endsection
@yield('name')— место вставки секции;@section('name') ... @endsection— содержимое секции;@parent— вставить содержимое родительской секции;@showвместо@endsection— вывести секцию сразу в родителе;@push('scripts')/@stack('scripts')— именованные стеки (удобно для JS/CSS из дочерних шаблонов).
Junior Зачем в формах @csrf и @method? Что будет без них?
@csrf вставляет скрытое поле с CSRF-токеном:
<form method="POST" action="/posts">
@csrf
</form>
HTML-формы отправляют cookies сессии, поэтому без проверки токена сайт уязвим к CSRF-атакам (чужой сайт отправляет форму от имени залогиненного пользователя). Middleware ValidateCsrfToken сверяет токен из поля _token с токеном сессии. Без @csrf — ошибка 419 Page Expired.
@method — эмуляция HTTP-глаголов, которых нет в HTML-формах (только GET/POST):
<form method="POST" action="/posts/1">
@csrf
@method('DELETE')
</form>
Генерирует <input type="hidden" name="_method" value="DELETE">, и Laravel маршрутизирует запрос как DELETE.
В API (SPA) вместо поля используется заголовок X-CSRF-TOKEN / Sanctum.
Middle Blade-компоненты: что это и чем отличаются от @include?
Компоненты — переиспользуемые куски UI с изоляцией данных. Два вида:
Класс + шаблон:
php artisan make:component Alert
class Alert extends Component
{
public function __construct(public string $type = 'info') {}
public function render() { return view('components.alert'); }
}
<x-alert type="error" :message="$errorText" />
Анонимные — только шаблон в resources/views/components/:
{{-- components/badge.blade.php --}}
@props(['color' => 'gray'])
<span class="badge-{{ $color }}">{{ $slot }}</span>
<x-badge color="red">Важно</x-badge>
Отличия от @include:
- атрибуты и слоты (
{{ $slot }}, именованные<x-slot:title>); :propпередаёт выражение PHP,prop— строку;- слияние атрибутов:
{{ $attributes->merge(['class' => 'base']) }}; - изоляция: компонент не видит переменные родителя, пока их явно не передать.
@include проще, но «протекает» контекстом и не имеет API слотов.