Вступление
Blade - простой, но мощный движок шаблонов, поставляемый с Laravel. В отличие от других популярных шаблонизаторов PHP, Blade не запрещает вам использовать простой PHP-код в ваших представлениях. Фактически, все представления Blade скомпилированы в простой PHP-код и кэшируются до тех пор, пока они не будут изменены, а это означает, что Blade практически не увеличивает накладные расходы на ваше приложение. Файлы блэйд-вида используют расширение файла и обычно хранятся в каталоге..blade.php
resources/views
Наследование шаблонов
Определение макета
Двумя основными преимуществами использования Blade являются наследование шаблонов и разделы . Для начала давайте рассмотрим простой пример. Сначала рассмотрим «мастер» макет страницы. Поскольку большинство веб-приложений поддерживают один и тот же общий макет на разных страницах, этот макет удобно определять как одно представление Blade:
<!-- Stored in resources/views/layouts/app.blade.php -->
<html>
<head>
<title>App Name - @yield('title')</title>
</head>
<body>
@section('sidebar')
This is the master sidebar.
@show
<div class="container">
@yield('content')
</div>
</body>
</html>
Как видите, этот файл содержит типичную разметку HTML. Тем не менее, принять к сведению @section
и директив. Директива, как следует из названия, определяет сечение содержания, в то время как директива используется для отображения содержимого данного раздела.@yield
@section
@yield
Теперь, когда мы определили макет для нашего приложения, давайте определим дочернюю страницу, которая наследует макет.
Расширение макета
При определении дочернего представления используйте директиву Blade, чтобы указать, какой макет дочернее представление должно «наследовать». Представления, расширяющие макет Blade, могут вводить контент в разделы макета с помощью директив. Помните, как видно из приведенного выше примера, содержимое этих разделов будет отображаться в макете с помощью :@extends
@section
@yield
<!-- Stored in resources/views/child.blade.php -->
@extends('layouts.app')
@section('title', 'Page Title')
@section('sidebar')
@parent
<p>This is appended to the master sidebar.</p>
@endsection
@section('content')
<p>This is my body content.</p>
@endsection
В этом примере sidebar
раздел использует директиву для добавления (а не перезаписи) содержимого к боковой панели макета. Директива будет заменено на содержимое макета , когда представление визуализируется.@parent
@parent
В отличие от предыдущего примера, этот
sidebar
раздел заканчивается@endsection
вместо@show
.@endsection
Директива будет определять только раздел в то время как@show
будет определять и сразу выход из этой секции.
Директива также принимает значение по умолчанию , в качестве второго параметра. Это значение будет отображено, если получаемый раздел не определен:@yield
@yield('content', View::make('view.name'))
Блейд-представления могут быть возвращены из маршрутов с помощью глобального view
помощника:
Route::get('blade', function () {
return view('child');
});
Компоненты и слоты
Компоненты и слоты обеспечивают аналогичные преимущества для разделов и макетов; однако, некоторые могут найти ментальную модель компонентов и слотов более легкой для понимания. Во-первых, давайте представим повторно используемый компонент «оповещения», который мы хотели бы использовать в нашем приложении:
<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">
{{ $slot }}
</div>
Переменная будет содержать контент мы хотим ввести в компонент. Теперь, чтобы построить этот компонент, мы можем использовать директиву Blade:{{ $slot }}
@component
@component('alert')
<strong>Whoops!</strong> Something went wrong!
@endcomponent
Иногда полезно определить несколько слотов для компонента. Давайте изменим наш компонент оповещения, чтобы добавить «заголовок». Именованные слоты могут отображаться путем «повторения» переменной, соответствующей их имени:
<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">
<div class="alert-title">{{ $title }}</div>
{{ $slot }}
</div>
Теперь мы можем внедрить содержимое в указанный слот, используя @slot
директиву. Любое содержимое, не входящее в @slot
директиву, будет передано компоненту в $slot
переменной:
@component('alert')
@slot('title')
Forbidden
@endslot
You are not allowed to access this resource!
@endcomponent
Передача дополнительных данных в компоненты
Иногда вам может потребоваться передать дополнительные данные компоненту. По этой причине вы можете передать массив данных в качестве второго аргумента @component
директиве. Все данные будут доступны для шаблона компонента в виде переменных:
@component('alert', ['foo' => 'bar'])
...
@endcomponent
Алиасинг компонентов
Если ваши компоненты Blade хранятся в подкаталоге, вы можете использовать псевдонимы для более легкого доступа. Например, представьте компонент Blade, который хранится в . Вы можете использовать метод для псевдонима компонента из в . Как правило, это должно быть сделано в методе вашего :resources/views/components/alert.blade.php
component
components.alert
alert
boot
AppServiceProvider
use Illuminate\Support\Facades\Blade;
Blade::component('components.alert', 'alert');
После того, как компонент был псевдоним, вы можете отобразить его с помощью директивы:
@alert(['type' => 'danger'])
You are not allowed to access this resource!
@endalert
Вы можете опустить параметры компонента, если у него нет дополнительных слотов:
@alert
You are not allowed to access this resource!
@endalert
Отображение данных
Вы можете отобразить данные, переданные в ваши представления Blade, заключив переменную в фигурные скобки. Например, учитывая следующий маршрут:
Route::get('greeting', function () {
return view('welcome', ['name' => 'Samantha']);
});
Вы можете отобразить содержимое name
переменной следующим образом:
Hello, {{ $name }}.
Операторы Blade автоматически отправляются через функцию PHP, чтобы предотвратить атаки XSS.
{{ }}
htmlspecialchars
Вы не ограничены отображением содержимого переменных, передаваемых в представление. Вы также можете повторить результаты любой функции PHP. Фактически, вы можете поместить любой PHP-код по вашему желанию в эхо-оператор Blade:
The current UNIX timestamp is {{ time() }}.
Отображение неэкранированных данных
По умолчанию операторы Blade автоматически отправляются через функцию PHP, чтобы предотвратить атаки XSS. Если вы не хотите, чтобы ваши данные были экранированы, вы можете использовать следующий синтаксис:{{ }}
htmlspecialchars
Hello, {!! $name !!}.
Будьте очень осторожны при отображении контента, предоставленного пользователями вашего приложения. Всегда используйте escape-синтаксис с двойными фигурными скобками, чтобы предотвратить атаки XSS при отображении пользовательских данных.
Рендеринг JSON
Иногда вы можете передать массив вашему представлению с намерением отобразить его как JSON, чтобы инициализировать переменную JavaScript. Например:
<script>
var app = <?php echo json_encode($array); ?>;
</script>
Однако вместо ручного вызова json_encode
вы можете использовать @json
директиву Blade. @json
Директива принимает те же аргументы, что и в PHP json_encode
функции:
<script>
var app = @json($array);
var app = @json($array, JSON_PRETTY_PRINT);
</script>
Вы должны использовать
@json
директиву только для визуализации существующих переменных в формате JSON. Шаблонирование Blade основано на регулярных выражениях, и попытки передать сложное выражение в директиву могут вызвать неожиданные сбои.
@json
Директива также полезна для высева компонентов Vue или атрибутов:data-*
<example-component :some-prop='@json($array)'></example-component>
Использование
@json
атрибутов in требует, чтобы он был заключен в одинарные кавычки.
HTML Entity Encoding
По умолчанию Blade (и e
помощник Laravel ) будут дважды кодировать сущности HTML. Если вы хотите отключить двойное кодирование, вызовите метод из метода вашего :Blade::withoutDoubleEncoding
boot
AppServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Blade::withoutDoubleEncoding();
}
}
Blade & JavaScript Framework
Поскольку многие JavaScript-фреймворки также используют «фигурные» скобки, чтобы указать, что данное выражение должно отображаться в браузере, вы можете использовать @
символ, чтобы сообщить механизму рендеринга Blade, что выражение должно остаться нетронутым. Например:
<h1>Laravel</h1>
Hello, @{{ name }}.
В этом примере @
символ будет удален Blade; однако выражение останется нетронутым движком Blade, что позволит ему вместо этого отображаться вашей средой JavaScript.{{ name }}
@verbatim
Директива
Если вы отображаете переменные JavaScript в большой части вашего шаблона, вы можете заключить HTML-код в @verbatim
директиву, чтобы вам не приходилось ставить перед каждым оператором Blade echo префикс @
:
@verbatim
<div class="container">
Hello, {{ name }}.
</div>
@endverbatim
Управляющие структуры
В дополнение к наследованию шаблонов и отображению данных Blade также предоставляет удобные ярлыки для общих структур управления PHP, таких как условные операторы и циклы. Эти ярлыки обеспечивают очень чистый и лаконичный способ работы со структурами управления PHP, оставаясь при этом знакомыми своим аналогам PHP.
IF
Вы можете построить if
заявления , используя , , и директивы. Эти директивы функционируют идентично своим аналогам PHP:@if
@elseif
@else
@endif
@if (count($records) === 1)
I have one record!
@elseif (count($records) > 1)
I have multiple records!
@else
I don't have any records!
@endif
Для удобства Blade также предоставляет @unless
директиву:
@unless (Auth::check())
You are not signed in.
@endunless
В дополнение к условным директивам, которые уже обсуждались, директивы @isset
and @empty
могут использоваться как удобные ярлыки для их соответствующих функций PHP:
@isset($records)
// $records is defined and is not null...
@endisset
@empty($records)
// $records is "empty"...
@endempty
Директивы аутентификации
В @auth
и @guest
директивы могут использоваться , чтобы быстро определить , если текущий пользователь проходит проверку подлинности или гость:
@auth
// The user is authenticated...
@endauth
@guest
// The user is not authenticated...
@endguest
При необходимости вы можете указать защиту аутентификации, которую следует проверять при использовании директив @auth
and @guest
:
@auth('admin')
// The user is authenticated...
@endauth
@guest('admin')
// The user is not authenticated...
@endguest
Директивы раздела
Вы можете проверить, содержит ли раздел содержимое, используя @hasSection
директиву:
@hasSection('navigation')
<div class="pull-right">
@yield('navigation')
</div>
<div class="clearfix"></div>
@endif
Переключение операторов
Заявления коммутатора могут быть построены с использованием , , , и директивы:@switch
@case
@break
@default
@endswitch
@switch($i)
@case(1)
First case...
@break
@case(2)
Second case...
@break
@default
Default case...
@endswitch
Loops
В дополнение к условным операторам Blade предоставляет простые директивы для работы со структурами циклов PHP. Опять же, каждая из этих директив функционирует идентично своим аналогам PHP:
@for ($i = 0; $i < 10; $i++)
The current value is {{ $i }}
@endfor
@foreach ($users as $user)
<p>This is user {{ $user->id }}</p>
@endforeach
@forelse ($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>No users</p>
@endforelse
@while (true)
<p>I'm looping forever.</p>
@endwhile
При зацикливании вы можете использовать переменную цикла для получения ценной информации о цикле, например, находитесь ли вы в первой или последней итерации цикла.
При использовании циклов вы также можете завершить цикл или пропустить текущую итерацию:
@foreach ($users as $user)
@if ($user->type == 1)
@continue
@endif
<li>{{ $user->name }}</li>
@if ($user->number == 5)
@break
@endif
@endforeach
Вы также можете включить условие с объявлением директивы в одну строку:
@foreach ($users as $user)
@continue($user->type == 1)
<li>{{ $user->name }}</li>
@break($user->number == 5)
@endforeach
Переменная Loop
При зацикливании $loop
переменная будет доступна внутри вашего цикла. Эта переменная обеспечивает доступ к некоторым полезным битам информации, таким как индекс текущего цикла и является ли это первой или последней итерацией цикла:
@foreach ($users as $user)
@if ($loop->first)
This is the first iteration.
@endif
@if ($loop->last)
This is the last iteration.
@endif
<p>This is user {{ $user->id }}</p>
@endforeach
Если вы находитесь во вложенном цикле, вы можете получить доступ к $loop
переменной родительского цикла через parent
свойство:
@foreach ($users as $user)
@foreach ($user->posts as $post)
@if ($loop->parent->first)
This is first iteration of the parent loop.
@endif
@endforeach
@endforeach
$loop
Переменная содержит также множество других полезных свойств:
Имущество | Описание |
---|---|
$loop->index |
Индекс текущей итерации цикла (начинается с 0). |
$loop->iteration |
Текущая итерация цикла (начинается с 1). |
$loop->remaining |
Итерации, оставшиеся в цикле. |
$loop->count |
Общее количество элементов в массиве, которое повторяется. |
$loop->first |
Является ли это первой итерацией цикла. |
$loop->last |
Является ли это последней итерацией цикла. |
$loop->even |
Является ли это четной итерацией в цикле. |
$loop->odd |
Является ли это нечетной итерацией в цикле. |
$loop->depth |
Уровень вложенности текущего цикла. |
$loop->parent |
Находясь во вложенном цикле, родительская переменная цикла. |
Комментарии
Blade также позволяет вам определять комментарии в ваших представлениях. Однако, в отличие от комментариев HTML, комментарии Blade не включаются в HTML, возвращаемый вашим приложением:
{{-- This comment will not be present in the rendered HTML --}}
PHP
В некоторых ситуациях полезно встроить PHP-код в ваши представления. Вы можете использовать @php
директиву Blade, чтобы выполнить блок простого PHP внутри вашего шаблона:
@php
//
@endphp
Хотя Blade предоставляет эту функцию, ее частое использование может быть сигналом о том, что в шаблон встроено слишком много логики.
Формы
CSRF Field
Каждый раз, когда вы определяете HTML-форму в своем приложении, вы должны включить в форму скрытое поле токена CSRF, чтобы промежуточное ПО защиты CSRF могло проверить запрос. Вы можете использовать @csrf
директиву Blade для генерации поля токена:
<form method="POST" action="/profile">
@csrf
...
</form>
Поле метода
Поскольку HTML - форма не может сделать PUT
, PATCH
или DELETE
запросы, то вам нужно добавить скрытое _method
поле , чтобы подменить этот HTTP глаголы. @method
Директива клинка может создать это поле для Вас:
<form action="/foo/bar" method="POST">
@method('PUT')
...
</form>
Ошибки валидации
@error
Директива может использоваться , чтобы быстро проверить, сообщения об ошибках проверок существуют для данного атрибута. Внутри @error
директивы вы можете вызвать $message
переменную для отображения сообщения об ошибке:
<!-- /resources/views/post/create.blade.php -->
<label for="title">Post Title</label>
<input id="title" type="text" class="@error('title') is-invalid @enderror">
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
Включая подвиды
Директива Blade позволяет вам включать представление Blade из другого представления. Все переменные, которые доступны для родительского представления, будут доступны для включенного представления:@include
<div>
@include('shared.errors')
<form>
<!-- Form Contents -->
</form>
</div>
Даже если включенное представление будет наследовать все данные, доступные в родительском представлении, вы также можете передать массив дополнительных данных во включенное представление:
@include('view.name', ['some' => 'data'])
Если вы попытаетесь создать несуществующее представление, Laravel выдаст ошибку. Если вы хотите включить представление, которое может присутствовать или не присутствовать, вы должны использовать директиву:@include
@includeIf
@includeIf('view.name', ['some' => 'data'])
Если вы хотите использовать представление в зависимости от заданного логического условия, вы можете использовать директиву:@include
@includeWhen
@includeWhen($boolean, 'view.name', ['some' => 'data'])
Чтобы включить первое представление, которое существует из данного массива представлений, вы можете использовать includeFirst
директиву:
@includeFirst(['custom.admin', 'admin'], ['some' => 'data'])
Вы должны избегать использования
__DIR__
и__FILE__
констант в ваших взглядах Клинка, так как они относятся к месту нахождения кэшируется, составитель зрения.
Псевдоним включает
Если ваши Blade-файлы хранятся в подкаталоге, вы можете создать псевдонимы для более легкого доступа. Например, представьте, что Blade- содержимое хранится со следующим содержимым:resources/views/includes/input.blade.php
<input type="{{ $type ?? 'text' }}">
Вы можете использовать include
метод для псевдонима включения из в . Как правило, это должно быть сделано в методе вашего :includes.input
input
boot
AppServiceProvider
use Illuminate\Support\Facades\Blade;
Blade::include('includes.input', 'input');
Когда псевдоним включен, вы можете отобразить его, используя псевдоним в качестве директивы Blade:
@input(['type' => 'email'])
Визуализация представлений для коллекций
Вы можете объединить циклы и включения в одну строку с помощью @each
директивы Blade :
@each('view.name', $jobs, 'job')
Первым аргументом является частичное представление, отображаемое для каждого элемента в массиве или коллекции. Второй аргумент - это массив или коллекция, для которой вы хотите выполнить итерацию, а третий аргумент - это имя переменной, которая будет назначена текущей итерации в представлении. Так, например, если вы выполняете итерации по массиву jobs
, как правило, вы захотите получить доступ к каждому заданию в качестве job
переменной в вашем частичном представлении. Ключ для текущей итерации будет доступен в качестве key
переменной в вашем частичном представлении.
Вы также можете передать четвертый аргумент @each
директиве. Этот аргумент определяет представление, которое будет отображаться, если данный массив пуст.
@each('view.name', $jobs, 'job', 'view.empty')
Представления, представленные через
@each
, не наследуют переменные от родительского представления. Если дочернее представление требует этих переменных, вы должны использовать и вместо этого.@foreach
@include
Стеки
Blade позволяет перемещаться в именованные стеки, которые могут быть отображены в другом месте в другом представлении или макете. Это может быть особенно полезно для указания любых библиотек JavaScript, требуемых вашими дочерними представлениями:
@push('scripts')
<script src="/example.js"></script>
@endpush
Вы можете вставлять в стек столько раз, сколько необходимо. Чтобы отобразить полное содержимое стека, передайте имя стека в @stack
директиву:
<head>
<!-- Head Contents -->
@stack('scripts')
</head>
Если вы хотите добавить содержимое в начало стека, вы должны использовать @prepend
директиву:
@push('scripts')
This will be second...
@endpush
// Later...
@prepend('scripts')
This will be first...
@endprepend
Сервисная инъекция
@inject
Директива может быть использована для получения услуги от Laravel контейнера службы. Первый передаваемый аргумент @inject
- это имя переменной, в которую будет помещена служба, а второй аргумент - имя класса или интерфейса службы, которую вы хотите разрешить:
@inject('metrics', 'App\Services\MetricsService')
<div>
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>
Удлиняющий Blade
Blade позволяет вам определять свои собственные директивы, используя directive
метод. Когда компилятор Blade встречает пользовательскую директиву, он вызывает предоставленный обратный вызов с выражением, которое содержит директива.
В следующем примере создается директива, которая форматирует данные , которые должны быть экземпляром :@datetime($var)
$var
DateTime
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Blade::directive('datetime', function ($expression) {
return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
});
}
}
Как видите, мы будем связывать format
метод с любым выражением, переданным в директиву. Итак, в этом примере окончательный PHP, сгенерированный этой директивой, будет:
<?php echo ($var)->format('m/d/Y H:i'); ?>
После обновления логики директивы Blade вам необходимо удалить все кэшированные представления Blade. Кэшированные виды Blade могут быть удалены с помощью команды Artisan.
view:clear
Пользовательские заявления If
Программирование пользовательской директивы иногда сложнее, чем необходимо при определении простых, пользовательских условных операторов. По этой причине Blade предоставляет метод, который позволяет быстро определять пользовательские условные директивы с помощью Closures. Например, давайте определим пользовательское условие, которое проверяет текущую среду приложения. Мы можем сделать это в методе нашего :Blade::if
boot
AppServiceProvider
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Blade::if('env', function ($environment) {
return app()->environment($environment);
});
}
Как только пользовательское условие было определено, мы можем легко использовать его в наших шаблонах:
@env('local')
// The application is in the local environment...
@elseenv('testing')
// The application is in the testing environment...
@else
// The application is not in the local or testing environment...
@endenv
0 комментариев