Шаблонизатор Blade и создание интерфейса
Создание переиспользуемых макетов страниц (layouts) и вывод динамических данных интернет-магазина в HTML.
Для генерации HTML-кода в Laravel используется мощный встроенный шаблонизатор Blade. В отличие от других шаблонизаторов (например, Twig или Smarty), Blade не ограничивает вас в использовании обычного PHP-кода внутри представлений, но предоставляет удобные директивы для распространенных задач, делая код намного чище и читабельнее. Файлы Blade имеют расширение .blade.php и хранятся в директории resources/views. Одной из главных особенностей Blade является встроенная защита от XSS-уязвимостей (Cross-Site Scripting). Когда вы выводите переменную с помощью двойных фигурных скобок {{ $variable }}, Blade автоматически пропускает данные через PHP-функцию htmlspecialchars. Это значит, что если злоумышленник введет в качестве своего имени скрипт <script>alert('hack')</script>, скрипт не выполнится в браузере, а отобразится как обычный текст.
Создание интерфейса интернет-магазина требует переиспользования общих элементов: шапки сайта (header), подвала (footer), меню навигации. В чистом PHP для этого использовались конструкции include. В Blade применяется концепция Наследования шаблонов (Layouts). Вы создаете главный каркас страницы (обычно resources/views/layouts/app.blade.php), где прописываете базовый HTML5, подключаете CSS/JS и определяете специальные 'якоря' с помощью директивы @yield('content'). Затем, при создании конкретной страницы (например, карточки товара), вы наследуете этот главный макет директивой @extends('layouts.app') и помещаете уникальный контент страницы внутрь секции @section('content') ... @endsection. При рендеринге Laravel собирает эти части воедино.
Для вывода динамических данных (например, списка товаров из базы данных, переданных из контроллера) Blade предоставляет удобные управляющие структуры, повторяющие логику PHP, но в более элегантном синтаксисе. Вместо громоздких открывающих и закрывающих тегов PHP, вы используете директиву @foreach. Например: @foreach($products as $product). Внутри цикла вы можете обращаться к свойствам объекта или массива товара. Также Blade имеет специфичные для фреймворка директивы. Например, в интернет-магазине часто нужно показывать разные элементы меню для авторизованных пользователей и гостей (кнопка 'Профиль' против 'Войти'). Для этого существуют директивы @auth (код внутри выполнится только если пользователь залогинен) и @guest (только для неавторизованных посетителей).
Важным аспектом является работа с формами. Поскольку мы разрабатываем безопасное приложение, любая POST-форма в Laravel должна быть защищена от атак межсайтовой подделки запроса (CSRF). Если вы создаете форму добавления товара в корзину, вы обязаны добавить внутрь тега <form> директиву @csrf. Эта директива генерирует скрытый input с уникальным токеном. При отправке формы Laravel проверяет, совпадает ли токен формы с токеном в сессии пользователя. Если токена нет или он неверный, запрос будет отклонен с ошибкой 419 (Page Expired).
<!-- resources/views/layouts/app.blade.php (Главный макет) -->
<!DOCTYPE html>
<html>
<head>
<title>My E-commerce</title>
</head>
<body>
<header>
<nav>
<a href="{{ route('products.index') }}">Каталог</a>
@auth
<a href="{{ route('profile') }}">Мой профиль</a>
<a href="{{ route('checkout') }}">Корзина</a>
@endauth
@guest
<a href="/login">Войти</a>
@endguest
</nav>
</header>
<main>
<!-- Сюда будет подставляться контент дочерних страниц -->
@yield('content')
</main>
</body>
</html>
<!-- resources/views/products/index.blade.php (Страница каталога) -->
@extends('layouts.app')
@section('content')
<h1>Каталог товаров</h1>
<div class="products-grid">
@foreach($products as $product)
<div class="product-card">
<!-- Безопасный вывод данных с защитой от XSS -->
<h2>{{ $product['name'] }}</h2>
<p>Цена: ${{ number_format($product['price'], 2) }}</p>
<!-- Форма добавления в корзину -->
<form action="/cart/add" method="POST">
@csrf <!-- Защита от CSRF атак обязательна! -->
<input type="hidden" name="product_id" value="{{ $product['id'] }}">
<button type="submit">В корзину</button>
</form>
</div>
@endforeach
</div>
@endsection