Основы Blade: вывод данных и директивы

Blade — шаблонизатор Laravel, который превращает данные в HTML с помощью лаконичных директив и автоматически защищает от XSS.

Суть: переменные выводятся через двойные фигурные скобки (с автоэкранированием), а управляющие конструкции — через директивы с символом @. Файлы шаблонов имеют расширение .blade.php.

Контроллер достаёт данные, но пользователю нужно показать их в виде красивой HTML-страницы. Можно лепить HTML прямо в PHP с кучей echo и <?php ?> — но это нечитаемо и опасно. Blade решает обе проблемы: даёт чистый синтаксис и автоматически экранирует вывод, защищая от XSS-атак.

Шаблоны Blade лежат в resources/views и имеют расширение .blade.php. Перед отдачей браузеру Laravel компилирует их в обычный PHP и кэширует — поэтому Blade быстрый. Вы пишете выразительный синтаксис, а движок превращает его в эффективный код.

Вывод данных

Главная конструкция Blade — двойные фигурные скобки для вывода переменной. Важнейшая деталь: такой вывод автоматически экранируется, то есть HTML-теги внутри данных превращаются в безопасный текст.

{{-- resources/views/profile.blade.php --}}
<h1>Профиль: {{ $user->name }}</h1>
<p>Email: {{ $user->email }}</p>

{{-- автоэкранирование: <script> станет безопасным текстом --}}
<p>Био: {{ $user->bio }}</p>

{{-- без экранирования (только для доверенного HTML!) --}}
<div>{!! $trustedHtml !!}</div>

Как работает под капотом

Двойные скобки компилируются в вызов htmlspecialchars(). Если пользователь введёт в поле «Био» строку <script>alert(1)</script>, Blade выведет её как текст, а не выполнит как код. Это и есть защита от XSS «по умолчанию». Конструкция {!! !!} отключает экранирование — её используют только для заведомо безопасного HTML.

  Данные из формы: <b>Привет</b>

  {{ $text }}   ->  &lt;b&gt;Привет&lt;/b&gt;   (показан текст, безопасно)
  {!! $text !!} ->  <b>Привет</b>          (выполнен HTML, опасно!)

  Правило: для пользовательских данных всегда {{ }}

Директивы управления

Условия и циклы пишутся через директивы с @ — чисто и без мешанины PHP-тегов:

@if ($products->isEmpty())
    <p>Товаров пока нет.</p>
@else
    <ul>
        @foreach ($products as $product)
            <li>{{ $product->name }} — {{ $product->price }} руб.</li>
        @endforeach
    </ul>
@endif

{{-- удобный @forelse для коллекций --}}
@forelse ($comments as $comment)
    <p>{{ $comment->text }}</p>
@empty
    <p>Комментариев нет.</p>
@endforelse

Смоделируем простейший рендеринг шаблона на Python: подстановка переменных плюс экранирование, как делает Blade.

Попробуй сам ▶

import html

def render(template, data):
    result = template
    for key, value in data.items():
        safe = html.escape(str(value))      # как {{ }} в Blade
        result = result.replace('{{ ' + key + ' }}', safe)
    return result

tpl = '<h1>Привет, {{ name }}!</h1><p>{{ bio }}</p>'
data = {'name': 'Анна', 'bio': '<script>hack()</script>'}
print(render(tpl, data))
# тег script экранирован -> атака не сработает

Частые ошибки

  • Использовать {!! !!} для пользовательских данных. Это открывает дверь XSS. Незаэкранированный вывод — только для доверенного HTML.
  • Логика в шаблоне. Сложные вычисления и запросы к базе в Blade — нарушение MVC; готовьте данные в контроллере.
  • Забыть закрыть директиву. Каждый @if, @foreach требует своего @endif, @endforeach.

Best practices

  • По умолчанию всегда выводите данные через {{ }} — безопасность бесплатна.
  • Держите шаблоны простыми: только отображение, без бизнес-логики.
  • Используйте @forelse для коллекций, которые могут оказаться пустыми.

В арсенале Blade есть множество директив-помощников, которые делают шаблоны выразительнее. Директива @isset($var) выводит блок только если переменная задана, @empty($items) — если коллекция пуста, а @auth и @guest показывают содержимое в зависимости от того, вошёл ли пользователь. Для условий есть лаконичный @unless (обратный @if) и тернарный хелпер {{ $active ? 'да' : 'нет' }}. Внутри циклов доступна служебная переменная $loop с полезными свойствами: $loop->index (номер итерации), $loop->first и $loop->last (первый/последний элемент), $loop->count (всего элементов). Это избавляет от ручных счётчиков и делает разметку чище. А директива @class(['active' => $isActive]) условно добавляет CSS-классы — мелочь, которая заметно сокращает шаблоны со сложной логикой оформления.

Итог: Blade даёт лаконичный и безопасный способ превращать данные в HTML. Двойные скобки экранируют вывод и защищают от XSS. Дальше научимся избегать дублирования вёрстки через наследование шаблонов.

Проверьте себя
1. Чем отличается {{ $x }} от {!! $x !!} в Blade?
AНичем
B{{ }} экранирует HTML (безопасно), {!! !!} выводит как есть (опасно для данных пользователя)
C{{ }} быстрее работает
D{!! !!} только для чисел
2. Какое расширение имеют файлы шаблонов Blade?
A.html
B.php
C.blade.php
D.twig