Laravel. Шаблонизатор Blade. Часть 1 из 2

05.11.2020

Теги: LaravelPHPWeb-разработкаТеорияФреймворкШаблонизаторШаблонСайта

Blade — простой, но мощный шаблонизатор, поставляемый с Laravel. В отличие от других популярных шаблонизаторов не ограничивает в использовании чистого php-кода в шаблонах. Все шаблоны Blade компилируются в чистый php-код и кешируются, до того момента, как в них будет внесены изменения.

Наследование шаблонов

Два основных преимущества использования Blade — наследование шаблонов и секции. Поскольку многие веб-приложения используют один общий макет для разных страниц, удобно определить этот макет как один layout-шаблон.

<html>
    <head>
        <title>@yield('title')</title>
    </head>
    <body>
        <div id="content">
            @yield('content')
        </div>
    </body>
</html>

Теперь создадим дочерний шаблон:

@extends('layouts.site')

@section('title', 'Заголовок страницы')

@section('content')
    <p>Это основной контент страницы.</p>
@endsection

Вместо @yield('content') (англ.выдавать) будет подставлено и отрисовано содержимое секции @section('content'). Директива @yield может принимать дефолтное значение в качестве второго аргумента. Это значение отрисовывается, если секция, которая должна располагаться на этом месте, не определена.

@yield('content', View::make('view.name'))

Рассмотрим еще один пример, где используем директиву @parent. Опять создадим layout-шаблон

<html>
    <head>
        <title>
            @yield('title', 'Заголовок по умолчанию')
        </title>
    </head>
    <body>
        <div id="content">
            @section('content')
                <p>Это контент страницы по умолчанию.</p>
            @show
        </div>
    </body>
</html>

И создадим два варианта дочернего шаблона:

@extends('layouts.site')

@section('title', 'Новый заголовок страницы')

@section('content')
    <p>Это контент замещает контент по умолчанию.</p>
@endsection
@extends('layouts.site')

@section('title', 'Новый заголовок страницы')

@section('content')
    @parent
    <p>Это контент дополняет контент по умолчанию.</p>
@endsection

Обратите внимание, что в родительском шаблоне вместо @yeld, мы используем @section и @show — что означает окончание секции и вывод содержимого. Другими словами, директивы @yeld и @show отвечают за вывод содержимого секции, а директивы @section и @endsection (синоним @stop) — только задают содержимое, но ничего не выводят.

Вывод переменных

Для вывода переменных, переданных в Blade-шаблон, используются двойные фигурные скобки:

Route::get('greeting', function () {
    return view('welcome', ['name' => 'Сергей']);
});
Добрый день, {{ $name }}!

Аналогично можно выводить результаты любых php-функций:

The current UNIX timestamp is {{ time() }}.

По умолчанию оператор {{...}} прогоняет вывод через функцию htmlspecialchars() для предотвращения XSS-атак. Если данные экранировать не нужно, можно использовать такой синтаксис:

Добрый день, {!! $name !!}!

Поскольку многие JavaScript-фреймворки тоже используют фигурные скобки, то можно использовать символ @, чтобы указать шаблонизатору Blade, что выражение должно остаться нетронутым.

Добрый день, @{{ name }}!

В этом примере Blade удалит символ @, но выражение {{ name }} останется нетронутым, что позволит JavaScript-фреймворку отрисовать его вместо Blade.

Директива @verbatim позволяет задать область шаблона, где выражения {{...}} не будут обрабатываться шаблонизатором Blade:

@verbatim
    <div class="container">
        Привет, {{ name }} {{ surname }}!
    </div>
@endverbatim

Включение подшаблонов

Директива @include позволяет включать один шаблон внутри другого шаблона. Все переменные, доступные родительскому шаблону, будут доступны и включаемому шаблону:

<div>
    @include('shared.errors')
    <form>
        <!-- Содержимое формы -->
    </form>
</div>

Хотя включаемый шаблон унаследует все переменные, доступные родительскому шаблону, можно передать в него массив дополнительных данных:

@include('view.name', ['some' => 'data'])

Само собой, при попытке @include шаблона, которого не существует — Laravel выдаст ошибку. Директива @includeIf позволяет подключить шаблон, который может и не существовать:

@includeIf('view.name', ['some' => 'data'])

Кроме того, можно подключать шаблон по условию, используя директиву @includeWhen (подключение состоится, если $boolean равно true) или директиву @includeUnless (подключение состоится, если $boolean равно false):

@includeWhen($boolean, 'view.name', ['some' => 'data'])
@includeUnless($boolean, 'view.name', ['some' => 'data'])

Условия в шаблонах

Директива @if(…) является полным аналогом if(…) языка PHP:

@if (count($items) === 1)
    <p>Только один элемент</p>
@elseif (count($items) > 1)
    <p>Несколько элементов</p>
@else
    <p>Вообще нет элементов</p>
@endif

Директива @unless(…) является противоположностью директиве @if(…):

@unless (Auth::check())
    <p>Пользователь не аутентифицирован</p>
@endunless

Директивы @isset(…) и @empty(…) — просто сокращения для соответствующих php-функций:

@isset($records)
    <p>Перменная определена и не является null</p>
@endisset
@empty($records)
    <p>Перменная пуста, равно нулю или null</p>
@endempty

Директивы @auth и @guest определяют видимость контента для залогиненного пользователя и наоборот.

@auth
    <p>Пользователь аутентифицирован</p>
@endauth
@guest
    <p>Пользователь не аутентифицирован</p>
@endguest

Директивы @switch, @case, @break, @default и @endswitch определяют видимость контента в зависимости от условий.

@switch($i)
    @case(1)
        <p>Будет показано, если совпало первое условие</p>
        @break
    @case(2)
        <p>Будет показано, если совпало второе условие</p>
        @break
    @default
        <p>Если не совпало ни одно из условий</p>
@endswitch

Циклы в шаблонах

В дополнение к условным операторам есть возможность для работы с конструкциями циклов:

@for ($i = 0; $i < 10; $i++)
    <p>Текущее значение переменной цикла {{ $i }}</p>
@endfor
@foreach ($users as $user)
    <p>Текущий пользователь — {{ $user->name }}</p>
@endforeach
@forelse ($users as $user)
    <p>Текущий пользователь — {{ $user->name }}</p>
@empty
    <p>Нет найдено пользователей</p>
@endforelse
@while (true)
    <p>Этот цикл будет продолжаться вечно</p>
@endwhile

При работе с циклами можно выйти из цикла или пропустить текущую итерацию:

<ul>
@foreach ($users as $user)
    @if ($user->admin)
        @continue
    @endif
    <li>Текущий пользователь — {{ $user->name }}</li>
    @if ($user->id == 10)
        @break
    @endif
@endforeach
</ul>

Также можно задать условие для @continue и @break:

<ul>
@foreach ($users as $user)
    @continue($user->admin)
    <li>Текущий пользователь — {{ $user->name }}</li>
    @break($user->id == 10)
@endforeach
</ul>

При работе с циклами — внутри цикла будет доступна переменная $loop. Эта переменная позволяет определить текущий индекс цикла, является ли текущая итерация первой или последней и так далее.

@foreach ($users as $user)
    @if ($loop->first)
        <p>Это первая итерация цикла</p>
    @endif
    @if ($loop->last)
        <p>Это последняя итерация цикла</p>
    @endif
    <p>Текущий пользователь — {{ $user->name }}</p>
@endforeach
Свойство Описание
$loop->index Индекс текущей итерации цикла (начинается с 0)
$loop->iteration Номер текущей итерации цикла (начинается с 1)
$loop->remaining Число оставшихся итераций цикла
$loop->count Общее число элементов массива
$loop->first Первая итерация цикла?
$loop->last Последняя итерация цикла?
$loop->even Чётная итерация цикла?
$loop->odd Нечётная итерация цикла?
$loop->depth Уровень вложенности текущего цикла
$loop->parent Переменная $loop родительского цикла

Шаблоны для коллекций

Часто возникает ситуация, когда надо в цикле перебрать массив и для отрисовки каждого элемента массива подключить шаблон:

<ul>
@foreach ($users as $user)
    @include('parts.user', ['user' => $user])
@endforeach
</ul>
<!-- шаблон resources/views/parts/user.blade.php -->
<li>Пользователь {{ $user->name }}, почта {{ $user->email }}</li>

Вместо foreach() и @include() можно использовать директиву @each():

@each('parts.user', $users, 'user')

Четветртый аргумент @each() задает шаблон, который будет использован, если массив пустой:

@each('parts.user', $users, 'user', 'parts.empty')

Поиск: Laravel • PHP • Web-разработка • Фреймворк • Шаблонизатор • Шаблон сайта • Теория • View • Blade

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.