Может войдёшь?
Черновики Написать статью Профиль

Шаблоны Blade

перевод документация 5.х

  1. 1. Введение
  2. 2. Наследование шаблонов
    1. 2.1. Определение макета
    2. 2.2. Наследование макета
  3. 3. Отображение данных
    1. 3.1. Blade и JavaScript-фреймворки
  4. 4. Управляющие конструкции
    1. 4.1. Оператор If
    2. 4.2. Циклы
    3. 4.3. Переменная Loop
    4. 4.4. Комментарии
    5. 4.5. PHP
  5. 5. Включение подшаблонов
    1. 5.1. Отрисовка представлений для коллекций
  6. 6. Стеки
  7. 7. Внедрение сервисов
  8. 8. Наследование Blade
Этот перевод актуален для англоязычной документации на (ветка 5.3) , (ветка 5.2) и (ветка 5.1). Опечатка? Выдели и нажми Ctrl+Enter.

Введение

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

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

Определение макета

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

PHP
<!-- Хранится в resources/views/layouts/app.blade.php -->

<
html>
  <
head>
    <
title>App Name - @yield('title')</title>
  </
head>
  <
body>
    @
section('sidebar')
      
Это главная боковая панель.
    @
show

    
<div class="container">
      @yield(
'content')
    </
div>
  </
body>
</
html>

Как видите, этот файл имеет типичную HTML-разметку. Но обратите внимание на директивы @section и @yield. Директива @section, как следует из её названия, определяет секцию содержимого, а директива @yield используется для отображения содержимого данной секции.

Мы определили макет для нашего приложения, давайте определим дочернюю страницу, которая унаследует макет.

Наследование макета

При определении дочернего представления используйте Blade-директиву @extends для указания макета, который должен быть «унаследован» дочерним представлением. Представления, которые наследуют макет Blade, могут внедрять содержимое в секции макета с помощью директив @section. Запомните, как видно из приведённого выше примера, содержимое этих секций будет отображено в макете при помощи @yield:

PHP
<!-- Хранится в resources/views/child.blade.php -->

@extends(
'layouts.app')

@
section('title''Page Title')

@
section('sidebar')
    @
parent

    
<p>Это дополнение к основной боковой панели.</p>
@
endsection

@section('content')
    <
p>Это содержимое тела страницы.</p>
@
endsection

В этом примере секция sidebar использует директиву @parent для дополнения (а не перезаписи) содержимого к боковой панели макета. Директива @parent будет заменена содержимым макета при отрисовке представления.

Blade-представления могут быть возвращены из маршрутов при помощи глобальной вспомогательной функции PHPview():

PHP
Route::get('blade', function () {
  return 
view('child');
});

Отображение данных

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

PHP
Route::get('greeting', function () {
  return 
view('welcome', ['name' => 'Samantha']);
});

Вы можете отобразить содержимое переменной name вот так:

PHP
Hello, {{ $name }}.

Вы не ограничены отображением только содержимого переменных, передаваемых в представление. Вы также можете выводить результаты любых PHP-функций. На самом деле, вы можете поместить любой необходимый PHP-код в оператор вывода Blade:

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

Blade-оператор PHP{{ }} автоматически отправляется через PHP-функцию PHPhtmlentities() для предотвращения XSS-атак.

Вывод переменных после проверки на существование

Иногда вам надо вывести значение переменной, но вы не уверены, задано ли оно. То есть вы хотите сделать так:

PHP
{{ isset($name) ? $name 'Default' }}

Вместо написания тернарного оператора Blade позволяет вам использовать такое удобное сокращение, которое будет скомпилировано в тернарный оператор, приведённый ранее:

PHP
{{ $name or 'Default' }}

Если переменная $name имеет значение, то оно будет отображено, иначе будет выведено слово Default.

Вывод неэкранированных данных

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

PHP
Hello, {!! $name !!}.

Будьте очень осторожны и экранируйте переменные, которые содержат ввод от пользователя. Всегда используйте экранирование синтаксисом с двойными скобками, чтобы предотвратить XSS-атаки при отображении предоставленных пользователем данных.

Как показывает практика, вместо экранирования только пользовательских переменных безопаснее экранировать весь вывод, делая исключения только в редких случаях — прим. пер.

Blade и JavaScript-фреймворки

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

PHP
<h1>Laravel</h1>

Hello, @{{ name }}.

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

+ 5.3

добавлено в 5.3 ()

Директива PHP@verbatim

Если вы выводите JavaScript-переменные в большой части вашего шаблона, вы можете обернуть HTML директивой PHP@verbatim, тогда вам не нужно будет ставить символ PHP@ перед каждым оператором вывода Blade:

PHP
@verbatim
  
<div class="container">
    
Hello, {{ name }}.
  </
div>
@
endverbatim

Управляющие конструкции

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

Оператор If

Вы можете конструировать оператор PHPif при помощи директив PHP@if, PHP@elseif, PHP@else и PHP@endif. Эти директивы работают идентично своим PHP-прообразам:

PHP
@if (count($records) === 1)
  
Здесь есть одна запись!
@elseif (
count($records) > 1)
  
Здесь есть много записей!
@else
  
Здесь нет записей!
@endif

Для удобства Blade предоставляет и директиву PHP@unless:

PHP
@unless (Auth::check())
    
Вы не вошли в систему.
@
endunless
+ 5.2

добавлено в 5.2 ()

Также вы можете определить, есть ли содержимое в данной секции макета, с помощью директивы PHP@hasSection:

PHP
<title>
  @
hasSection ('title')
    @yield(
'title') - Название приложения
  
@else
    
Название приложения
  
@endif
</
title>

Циклы

В дополнение к условным операторам Blade предоставляет простые директивы для работы с конструкциями циклов PHP. Данные директивы тоже идентичны их PHP-прообразам:

PHP
@for ($i 0$i 10$i++)
  
Текущее значение: {{ $i }}
@endfor

@foreach (
$users as $user)
  <
p>Это пользователь {{ $user->id }}</p>
@endforeach

@
forelse($users as $user)
  <
li>{{ $user->name }}</li>
@empty
  <
p>Нет пользователей</p>
@
endforelse

@while (true)
  <
p>Это будет длиться вечно.</p>
@endwhile
+ 5.3 5.2

добавлено в 5.3 () 5.2 ()

При работе с циклами вы можете использовать переменную loop для получения полезной информации о цикле, например, находитесь ли вы на первой или последней итерации цикла.

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

PHP
@foreach ($users as $user)
  @if (
$user->type == 1)
    @continue
  @endif

  <
li>{{ $user->name }}</li>

  @if (
$user->number == 5)
    @break
  @endif
@endforeach

Также можно включить условие в строку объявления директивы:

PHP
@foreach ($users as $user)
  @continue(
$user->type == 1)

  <
li>{{ $user->name }}</li>

  @break(
$user->number == 5)
@endforeach
+ 5.3

добавлено в 5.3 ()

Переменная Loop

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

PHP
@foreach ($users as $user)
  @if (
$loop->first)
    
Это первая итерация.
  @endif

  @if (
$loop->last)
    
Это последняя итерация.
  @endif

  <
p>Это пользователь {{ $user->id }}</p>
@endforeach

Если вы во вложенном цикле, вы можете обратиться к переменной PHP$loop родительского цикла через свойство PHPparent:

PHP
@foreach ($users as $user)
  @foreach (
$user->posts as $post)
    @if (
$loop->parent->first)
      
Это первая итерация родительского цикла.
    @endif
  @endforeach
@endforeach

Переменная PHP$loop содержит также множество других полезных свойств:

Свойство Описание
$loop->index Индекс текущей итерации цикла (начинается с 0).
$loop->iteration Текущая итерация цикла(начинается с 1).
$loop->remaining Число оставшихся итераций цикла.
$loop->count Общее число элементов итерируемого массива.
$loop->first Первая ли это итерация цикла.
$loop->last Последняя ли это итерация цикла.
$loop->depth Уровень вложенности текущего цикла.
$loop->parent Переменная loop родительского цикла, для вложенного цикла.

Комментарии

Blade также позволяет вам определить комментарии в ваших представлениях. Но в отличие от HTML-комментариев, Blade-комментарии не включаются в HTML-код, возвращаемый вашим приложением:

PHP
{{-- Этого комментария не будет в итоговом HTML --}}

PHP

В некоторых случаях бывает полезно встроить PHP-код в ваши представления. Вы можете использовать Blade-директиву PHP@php для выполнения блока чистого PHP в вашем шаблоне:

PHP
  @php
      
//
  
@endphp

Несмотря на то, что в Blade есть эта возможность, её частое использование может быть сигналом того, что у вас слишком много логики, встроенной в шаблон.

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

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

PHP
<div>
  @include(
'shared.errors')

  <
form>
    <!-- 
Содержимое формы -->
  </
form>
</
div>

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

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

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

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

Вам следует избегать использования констант __DIR__ и __FILE__ в ваших Blade-представлениях, поскольку они будут ссылаться на расположение кешированных, скомпилированных представлений.

Отрисовка представлений для коллекций

Вы можете комбинировать циклы и включения в одной строке при помощи Blade-директивы @each:

PHP
@each('view.name'$jobs'job')

Первый аргумент — часть представления, которую надо отрисовать для каждого элемента массива или коллекции. Второй аргумент — массив или коллекция для перебора, а третий — имя переменной, которое будет назначено для текущей итерации в представлении. Например, если вы перебираете массив jobs, то скорее всего захотите обращаться к каждому элементу как к переменной job внутри вашей части представления. Ключ для текущей итерации будет доступен в виде переменной key в вашей части представления.

Вы также можете передать четвёртый аргумент в директиву @each. Этот аргумент определяет представление, которое будет отрисовано, если данный массив пуст.

PHP
@each('view.name'$jobs'job''view.empty')
+ 5.3 5.2

добавлено в 5.3 () 5.2 ()

Стеки

Blade позволяет использовать именованные стеки, которые могут быть отрисованы где-нибудь ещё в другом представлении или макете. Это удобно в основном для указания любых JavaScript-библиотек, требуемых для ваших дочерних представлений:

PHP
@push('scripts')
  <
script src="/example.js"></script>
@endpush

«Пушить» в стек можно сколько угодно раз. Для отрисовки всего содержимого стека передайте имя стека в директиву PHP@stack:

PHP
<head>
  <!-- 
Содержимое заголовка -->

  @
stack('scripts')
</
head>

Внедрение сервисов

Директива @inject служит для извлечения сервиса из сервис-контейнера Laravel. Первый аргумент, передаваемый в @inject, это имя переменной, в которую будет помещён сервис. А второй аргумент — имя класса или интерфейса сервиса, который вы хотите извлечь:

PHP
@inject('metrics''App\Services\MetricsService')

<
div>
  
Месячный доход: {{ $metrics->monthlyRevenue() }}.
</
div>

Наследование Blade

Blade позволяет вам определять даже свои собственные директивы с помощью метода PHPdirective(). Когда компилятор Blade встречает пользовательскую директиву, он вызывает предоставленный обратный вызов с содержащимся в директиве выражением.

Следующий пример создаёт директиву PHP@datetime($var), которая форматирует данный PHP$var, который должен быть экземпляром DateTime:

PHP
<?php

namespace App\Providers;

use 
Illuminate\Support\Facades\Blade;
//для версии 5.2 и ранее:
//use Blade;
use Illuminate\Support\ServiceProvider;

class 
AppServiceProvider extends ServiceProvider
{
  
/**
   * Выполнение после-регистрационной загрузки сервисов.
   *
   * @return void
   */
  
public function boot()
  {
    
Blade::directive('datetime', function ($expression) {
      return 
"<?php echo ($expression)->format('m/d/Y H:i'); ?>";
    });
  }

  
/**
   * Регистрация привязок в контейнере.
   *
   * @return void
   */
  
public function register()
  {
    
//
  
}
}

Как видите, мы прицепили метод PHPformat() к тому выражению, которое передаётся в директиву. Поэтому финальный PHP-код, сгенерированный этой директивой, будет таким:

PHP
<?php echo ($var)->format('m/d/Y H:i'); ?>
+ 5.3 5.2

добавлено в 5.3 () 5.2 ()

После изменения логики директивы Blade вам надо удалить все кешированные представления Blade. Это можно сделать Artisan-командой shview:clear.

Комментарии (4)

olko

спасибо огромное!

berki

https://laravel.ru/docs/v5/blade#отображение-5
$name or 'Default' у меня не работает. В чем может быть проблема? Undefined variable: name

Lerua

попробуйте так :
$name ?? 'Default'

begovik

А если наоборот, файл app.blade.php хранится во resources/views, а подключаемые элементы во resources/views/layouts, как тогда app.blade.php подключить в @extends?

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.