Версія фреймворка: 8.x

Blade шаблони

Вступ

Blade - це простий, але потужний двигун для створення шаблонів, що постачається разом із Laravel. На відміну від інших популярних PHP-шаблоністів, Blade не обмежує використання звичайного PHP-коду у ваших Viewх. Насправді всі View Blade компілюються у звичайний PHP-код і кешуються, доки їх не модифікують, тобто Blade додає по суті нульові накладні витрати у вашу програму. Файли перегляду 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@extendsдиректива, щоб вказати, який макет дочірній Шаблон повинен "успадкувати". Представлення, які розширюють макет Blade, можуть вливати вміст у розділи макета за допомогою@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Директива буде замінена вмістом макета, коли подається View.

На відміну від попереднього прикладу, цеsidebarрозділ закінчується на@endsectionзамість@show.@endsectionДиректива визначатиме лише розділ while@showвизначить інегайно врожайрозділу.

@yieldДиректива також приймає значення за замовчуванням як другий параметр. Це значення буде відображено, якщо вказаний розділ не визначений:

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

Види Blade можуть повертатися з маршрутів за допомогою глобальногоviewпомічник:

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

Відображення даних

Ви можете відображати дані, передані у ваші View Blade, обертаючи змінну фігурними дужками. Наприклад, враховуючи такий маршрут:

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

Ви можете відобразити вмістnameтака змінна:

Hello, {{ $name }}.
Blade{{ }}Statements автоматично надсилаються через PHPhtmlspecialcharsфункція для запобігання атакам XSS.

Ви не обмежуєтесь відображенням вмісту змінних, переданих у View. Ви також можете повторити результати будь-якої функції PHP. Насправді ви можете помістити будь-який PHP-код, який хочете, всередину інструкції Blade echo:

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

Відображення незахищених даних

За замовчуванням Blade{{ }}Statements автоматично надсилаються через PHPhtmlspecialchars function to prevent XSS attacks. If you do not want your data to be escaped, you may use the following syntax:

Hello, {!! $name !!}.
Будьте дуже обережні, повторюючи контент, який надають користувачі вашої програми. Завжди використовуйте захищений синтаксис подвійних фігурних дужок, щоб запобігти атакам XSS під час відображення даних, наданих користувачем.

Rendering JSON

Іноді ви можете передати масив своєму поданню з наміром зробити його як JSON, щоб ініціалізувати змінну JavaScript. Наприклад:

<script>
    var app = <?php echo json_encode($array); ?>;
</script>

Однак замість виклику вручнуjson_encode, ви можете використовувати@jsonДиректива Blade.@jsonДиректива приймає ті самі аргументи, що і PHPjson_encodeфункція. За замовчуванням@jsonдиректива викликаєjson_encodeфункція за допомогоюJSON_HEX_TAG,JSON_HEX_APOS,JSON_HEX_AMP, іJSON_HEX_QUOTпрапори:

<script>
    var app = @json($array);

    var app = @json($array, JSON_PRETTY_PRINT);
</script>
Вам слід використовувати лише@jsonдиректива відображати існуючі змінні як JSON. Шаблон Blade базується на регулярних виразах, і спроби передати складний вираз директиві можуть спричинити несподівані помилки.

Кодування сутності HTML

За замовчуванням Blade (і Laravelehelper) буде подвійно кодувати 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 Frameworks

Оскільки багато фреймворків JavaScript також використовують "фігурні" фігурні дужки, щоб вказати, що даний вираз повинен відображатися у браузері, ви можете використовувати@символ, який повідомляє механізм рендеринга Blade про вираз, повинен залишатися незайманим. Наприклад:

<h1>Laravel</h1>

Hello, @{{ name }}.

У цьому прикладі@символ буде видалений Blade; однак,{{ name }}вираз залишиться незайманим механізмом Blade, що дозволить його натомість рендерити вашим фреймворком JavaScript.

@символ також може використовуватися для виходу з директив Blade:

{{-- Blade --}}
@@json()

<!-- HTML output -->
@json()

@verbatimДиректива

Якщо ви відображаєте змінні JavaScript у великій частині свого шаблону, ви можете обернути HTML у@verbatimдирективи, так що вам не потрібно префіксувати кожен оператор Blade echo префіксом@символ:

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

Структури управління

На додаток до успадкування шаблону та відображення даних, Blade також пропонує зручні ярлики для загальних структур управління PHP, таких як умовні оператори та цикли. Ці комбінації клавіш забезпечують дуже чіткий, стислий спосіб роботи зі структурами управління PHP, залишаючись при цьому знайомими для своїх колег PHP.

Якщо Заяви

Ви можете побудуватиifзаяви з використанням@if,@elseif,@else, і@endifдирективи. Ці директиви функціонують ідентично своїм аналогам PHP:

@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і@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і@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

Ви можете використовуватиsectionMissingдиректива, щоб визначити, чи не має розділ змісту:

@sectionMissing('navigation')
    <div class="pull-right">
        @include('default-navigation')
    </div>
@endif

Директиви про довкілля

Ви можете перевірити, чи працює програма у виробничому середовищі, використовуючи@productionдиректива:

@production
    // Production specific content...
@endproduction

Або ви можете визначити, чи працює програма в певному середовищі, використовуючи@envдиректива:

@env('staging')
    // The application is running in "staging"...
@endenv

@env(['staging', 'production'])
    // The application is running in "staging" or "production"...
@endenv

Заяви про перемикання

Інструкції комутатора можна побудувати за допомогою@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

Змінна Loops

Під час циклу a$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 Whether this is the first iteration through the loop.
$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-код у свої View. Ви можете використовувати Blade@phpдля виконання блоку простого PHP у вашому шаблоні:

@php
    //
@endphp
Хоча Blade надає цю функцію, її часто використання може свідчити про те, що у вашому шаблоні закладено занадто багато логіки.

@onceДиректива

@onceДиректива дозволяє визначити частину шаблону, яка буде оцінюватися лише один раз за цикл рендерингу. Це може бути корисно для введення заданого фрагмента JavaScript у заголовок сторінки за допомогоюстеки. Наприклад, якщо ви рендеріть заданийкомпонентв межах циклу, можливо, ви захочете натиснути JavaScript у заголовок лише під час першого відображення компонента:

@once
    @push('scripts')
        <script>
            // Your custom JavaScript...
        </script>
    @endpush
@endonce

Форми

Поле CSRF

Кожного разу, коли ви визначаєте форму HTML у своїй програмі, ви повинні включити приховане поле маркера CSRF у форму, щоб цезахист CSRFMiddleware може перевірити запит. Ви можете використовувати@csrfДиректива Blade для створення поля маркера:

<form method="POST" action="/profile">
    @csrf

    ...
</form>

Поле методу

Оскільки форми HTML неможливо зробитиPUT,PATCH, абоDELETEзапити, вам потрібно буде додати прихований_methodполе для підробки цих HTTP-дієслів.@methodДиректива Blade може створити для вас це поле:

<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

Ви можете пройтиназва конкретного пакета помилокяк другий параметр до@errorдиректива для отримання повідомлень про помилки перевірки на сторінках, що містять кілька форм:

<!-- /resources/views/auth.blade.php -->

<label for="email">Email address</label>

<input id="email" type="email" class="@error('email', 'login') is-invalid @enderror">

@error('email', 'login')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror

Компоненти

Компоненти та слоти забезпечують подібні переваги для розділів та макетів; проте, деяким може бути ментальна модель компонентів та слотів легшою для розуміння. Існує два підходи до написання компонентів: компоненти на основі класу та анонімні компоненти.

Щоб створити компонент на основі класу, ви можете використовуватиmake:componentartisan командування. Щоб проілюструвати, як використовувати компоненти, ми створимо простуAlertкомпонент.make:componentкоманда розмістить компонент уApp\View\Componentsкаталог:

php artisan make:component Alert

make:componentкоманда також створить шаблон View для компонента. Шаблон буде розміщено вresources/views/componentsкаталог.

Ви також можете створювати компоненти в підкаталогах:

php artisan make:component Forms/Input

Команда вище створить файлInputкомпонент вApp\View\Components\Formsі View буде розміщено вresources/views/components/formsкаталог.

Реєстрація компонентів пакунку вручну

Під час написання компонентів для власного додатка компоненти автоматично виявляються вapp/View/Componentsкаталог іresources/views/componentsкаталог.

Однак, якщо ви створюєте пакет, який використовує компоненти Blade, вам потрібно буде вручну зареєструвати клас свого компонента та його псевдонім тегу HTML. Зазвичай слід реєструвати свої компоненти вbootметод постачальника послуг вашого пакета:

use Illuminate\Support\Facades\Blade;

/**
 * Bootstrap your package's services.
 */
public function boot()
{
    Blade::component('package-alert', AlertComponent::class);
}

Після того, як ваш компонент буде зареєстровано, він може бути відтворений за допомогою його псевдоніма:

<x-package-alert/>

Крім того, ви можете використовуватиcomponentNamespaceметод для автоматичного завантаження класів компонентів за домовленістю. Наприклад, aNightshadeпакет може матиCalendarіColorPickerкомпоненти, що знаходяться в межахPackage\Views\Componentsпростір імен:

use Illuminate\Support\Facades\Blade;

/**
 * Bootstrap your package's services.
 */
public function boot()
{
    Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}

Це дозволить використовувати компоненти пакету їхнім простором імен постачальника за допомогоюpackage-name::синтаксис:

<x-nightshade::calendar />
<x-nightshade::color-picker />

Блейд автоматично виявляє клас, який пов'язаний з цим компонентом, за допомогою паскаля-регістру імені компонента. Підкаталоги також підтримуються за допомогою Tagging "крапка".

Відображення компонентів

Для відображення компонента ви можете використовувати тег компонента Blade в одному зі своїх шаблонів Blade. Теги компонентів Blade починаються з рядкаx-а потім ім’я справи шашлику класу компонента:

<x-alert/>

<x-user-profile/>

Якщо клас компонента вкладений глибше вApp\View\Componentsкаталог, ви можете використовувати.символ для Tagging вкладеності в каталог. Наприклад, якщо ми припустимо, що компонент знаходиться вApp\View\Components\Inputs\Button.php, ми можемо зробити це так:

<x-inputs.button/>

Передача даних компонентам

Ви можете передавати дані компонентам Blade за допомогою атрибутів HTML. Твердо закодовані примітивні значення можуть передаватися компоненту за допомогою простих атрибутів HTML. PHP-вирази та змінні повинні передаватися компоненту через атрибути, що використовують:символ як префікс:

<x-alert type="error" :message="$message"/>

Ви повинні визначити необхідні дані компонента в його конструкторі класів. Усі загальнодоступні властивості компонента автоматично будуть доступні для перегляду компонента. Не потрібно передавати дані до View з компонентаrenderметод:

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
    /**
     * The alert type.
     *
     * @var string
     */
    public $type;

    /**
     * The alert message.
     *
     * @var string
     */
    public $message;

    /**
     * Create the component instance.
     *
     * @param  string  $type
     * @param  string  $message
     * @return void
     */
    public function __construct($type, $message)
    {
        $this->type = $type;
        $this->message = $message;
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\View\View|\Closure|string
     */
    public function render()
    {
        return view('components.alert');
    }
}

Коли ваш компонент відображається, ви можете відображати вміст загальнодоступних змінних вашого компонента, повторюючи змінні за іменем:

<div class="alert alert-{{ $type }}">
    {{ $message }}
</div>

Кожух

Аргументи конструктора компонентів слід вказувати за допомогоюcamelCase, покиkebab-caseслід використовувати при посиланні на імена аргументів у ваших атрибутах HTML. Наприклад, враховуючи такий конструктор компонентів:

/**
 * Create the component instance.
 *
 * @param  string  $alertType
 * @return void
 */
public function __construct($alertType)
{
    $this->alertType = $alertType;
}

$alertTypeаргумент може бути поданий так:

<x-alert alert-type="danger" />

Компонентні методи

Окрім загальнодоступних змінних, доступних для вашого шаблону компонента, також можуть бути виконані будь-які відкриті методи на компоненті. Наприклад, уявіть компонент, який маєisSelectedметод:

/**
 * Determine if the given option is the current selected option.
 *
 * @param  string  $option
 * @return bool
 */
public function isSelected($option)
{
    return $option === $this->selected;
}

Ви можете виконати цей метод із шаблону компонента, викликаючи змінну, що відповідає імені методу:

<option {{ $isSelected($value) ? 'selected="selected"' : '' }} value="{{ $value }}">
    {{ $label }}
</option>

Використання атрибутів та слотів всередині класу

Компоненти Blade також дозволяють отримати доступ до імені компонента, атрибутів та слота всередині методу візуалізації класу. Однак для того, щоб отримати доступ до цих даних, вам слід повернути Закриття від компонентаrenderметод. Закриття отримає a$dataмасив як єдиний аргумент:

/**
 * Get the view / contents that represent the component.
 *
 * @return \Illuminate\View\View|\Closure|string
 */
public function render()
{
    return function (array $data) {
        // $data['componentName'];
        // $data['attributes'];
        // $data['slot'];

        return '<div>Components content</div>';
    };
}

componentNameдорівнює імені, що використовується в тегу HTML післяx-префікс. Тому<x-alert />'scomponentNameбудеalert.attributesЕлемент буде містити всі атрибути, які були присутні в тезі HTML.slotелементом єIlluminate\Support\HtmlStringекземпляр із вмістом слота від компонента.

Закриття має повернути рядок. Якщо повернутий рядок відповідає існуючому шаблону, цей Шаблон буде відтворений; в іншому випадку повернутий рядок буде оцінено як вбудований Шаблон Blade.

Додаткові залежності

Якщо ваш компонент вимагає залежностей від Laravel'sслужбовий контейнер, ви можете перерахувати їх перед будь-яким з атрибутів даних компонента, і вони автоматично вводяться контейнером:

use App\Services\AlertCreator

/**
 * Create the component instance.
 *
 * @param  \App\Services\AlertCreator  $creator
 * @param  string  $type
 * @param  string  $message
 * @return void
 */
public function __construct(AlertCreator $creator, $type, $message)
{
    $this->creator = $creator;
    $this->type = $type;
    $this->message = $message;
}

Управління атрибутами

Ми вже розглядали, як передавати атрибути даних компоненту; однак іноді може знадобитися вказати додаткові атрибути HTML, наприкладclass, які не є частиною даних, необхідних для функціонування компонента. Зазвичай ці додаткові атрибути потрібно передавати кореневому елементу шаблону компонента. Наприклад, уявіть, що ми хочемо зробити файлalertкомпонент так:

<x-alert type="error" :message="$message" class="mt-4"/>

Всі атрибути, які не є частиною конструктора компонента, будуть автоматично додані до "мішка атрибутів" компонента. Цей пакет атрибутів автоматично стає доступним компоненту через$attributesзмінна. Усі атрибути можуть бути відтворені в компоненті, повторюючи цю змінну:

<div {{ $attributes }}>
    <!-- Component Content -->
</div>
Використовуючи директиви, такі як@envбезпосередньо на компонент зараз не підтримується.

Атрибути за замовчуванням / об’єднані

Іноді вам може знадобитися вказати значення за замовчуванням для атрибутів або об'єднати додаткові значення в деякі атрибути компонента. Для цього ви можете використовувати атрибут bag'smergeметод:

<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
    {{ $message }}
</div>

Якщо ми припустимо, що цей компонент використовується так:

<x-alert type="error" :message="$message" class="mb-4"/>

Остаточний, відображений HTML компонента буде виглядати так:

<div class="alert alert-error mb-4">
    <!-- Contents of the $message variable -->
</div>

Некласове об’єднання атрибутів

При об'єднанні атрибутів, які не єclassатрибути, значення, надані вmergeМетод вважатиметься значеннями атрибуту за замовчуванням, які можуть бути замінені споживачем компонента. На відміну відclassатрибути, некласові атрибути не додаються один до одного. Наприклад, abuttonкомпонент може виглядати наступним чином:

<button {{ $attributes->merge(['type' => 'button']) }}>
    {{ $slot }}
</button>

Візуалізувати компонент кнопки за допомогою спеціальногоtype, це може бути вказано при споживанні компонента. Якщо тип не вказаний, тоbuttonбуде використовуватися тип:

<x-button type="submit">
    Submit
</x-button>

Візуалізований HTMLbuttonкомпонентом у цьому прикладі буде:

<button type="submit">
    Submit
</button>

Якщо вам потрібен атрибут, відмінний відclassщоб його значення складалися разом, ви можете використовуватиprependsметод:

<div {{ $attributes->merge(['data-controller' => $attributes->prepends('profile-controller')]) }}>
    {{ $slot }}
</div>

Атрибути фільтрації

Ви можете фільтрувати атрибути за допомогоюfilterметод. Цей метод приймає Закриття, яке повинно повернутисяtrueякщо ви хочете зберегти атрибут у мішці атрибутів:

{{ $attributes->filter(fn ($value, $key) => $key == 'foo') }}

Для зручності ви можете використовуватиwhereStartsWithметод отримання всіх атрибутів, ключі яких починаються з заданого рядка:

{{ $attributes->whereStartsWith('wire:model') }}

Використанняfirstметодом, ви можете відтворити перший атрибут у даному пакеті атрибутів:

{{ $attributes->whereStartsWith('wire:model')->first() }}

Слоти

Часто вам потрібно буде передати додатковий вміст своєму компоненту через "слоти". Давайте уявимо, що analertкомпонент, який ми створили, має таку розмітку:

<!-- /resources/views/components/alert.blade.php -->

<div class="alert alert-danger">
    {{ $slot }}
</div>

Ми можемо передавати вміст доslotшляхом введення вмісту в компонент:

<x-alert>
    <strong>Whoops!</strong> Something went wrong!
</x-alert>

Іноді компоненту може знадобитися відобразити кілька різних слотів у різних місцях усередині компонента. Давайте змінимо наш компонент оповіщення, щоб дозволити введення "заголовка":

<!-- /resources/views/components/alert.blade.php -->

<span class="alert-title">{{ $title }}</span>

<div class="alert alert-danger">
    {{ $slot }}
</div>

Ви можете визначити вміст названого слота за допомогоюx-slotтег. Будь-який вміст, який не знаходиться вx-slotтег буде переданий компоненту в$slotзмінна:

<x-alert>
    <x-slot name="title">
        Server Error
    </x-slot>

    <strong>Whoops!</strong> Something went wrong!
</x-alert>

Слоти

Якщо ви використовували фреймворк JavaScript, такий як Vue, можливо, ви знайомі з "масштабованими слотами", які дозволяють отримувати доступ до даних або методів з компонента у вашому слоті. Ви можете досягти подібної поведінки в Laravel, визначивши загальнодоступні методи або властивості для свого компонента та отримавши доступ до компонента у вашому слоті через$componentзмінна:

<x-alert>
    <x-slot name="title">
        {{ $component->formatAlert('Server Error') }}
    </x-slot>

    <strong>Whoops!</strong> Something went wrong!
</x-alert>

Inline Views компонентів

Для дуже маленьких компонентів може здатися громіздким управління як класом компонентів, так і шаблоном View компонента. З цієї причини ви можете повернути розмітку компонента безпосередньо зrenderметод:

/**
 * Get the view / contents that represent the component.
 *
 * @return \Illuminate\View\View|\Closure|string
 */
public function render()
{
    return <<<'blade'
        <div class="alert alert-danger">
            {{ $slot }}
        </div>
    blade;
}

Генерування компонентів вбудованого перегляду

Щоб створити компонент, який відображає вбудований Шаблон, ви можете використовуватиinlineпараметр при виконанніmake:componentкоманда:

php artisan make:component Alert --inline

Анонімні компоненти

Подібно до вбудованих компонентів, анонімні компоненти забезпечують механізм управління компонентом через один файл. Однак анонімні компоненти використовують один файл перегляду і не мають пов'язаного класу. Щоб визначити анонімний компонент, вам потрібно лише розмістити шаблон Blade у вашомуresources/views/componentsкаталог. Наприклад, припускаючи, що ви визначили компонент наresources/views/components/alert.blade.php:

<x-alert/>

Ви можете використовувати.символ, щоб вказати, чи компонент вкладений глибше всерединуcomponentsкаталог. Наприклад, припускаючи, що компонент визначений вresources/views/components/inputs/button.blade.php, ви можете зробити це так:

<x-inputs.button/>

Властивості даних / атрибути

Оскільки анонімні компоненти не мають жодного асоційованого класу, ви можете задатися питанням, як можна диференціювати, які дані повинні передаватися компоненту як змінні, а які атрибути слід розміщувати ватрибут сумка.

Ви можете вказати, які атрибути слід вважати змінними даних, використовуючи@propsвгорі шаблону Blade вашого компонента. Усі інші атрибути компонента будуть доступні через пакет атрибутів компонента. Якщо ви хочете надати змінній даних значення за замовчуванням, ви можете вказати ім'я змінної як ключ масиву, а значення за замовчуванням як значення масиву:

<!-- /resources/views/components/alert.blade.php -->

@props(['type' => 'info', 'message'])

<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
    {{ $message }}
</div>

Динамічні компоненти

Іноді вам може знадобитися відобразити компонент, але не знати, який компонент повинен бути відтворений до часу виконання. У цій ситуації ви можете використовувати вбудований Laraveldynamic-componentкомпонент для візуалізації компонента на основі значення середовища або змінної:

<x-dynamic-component :component="$componentName" class="mt-4" />

Including Subviews

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

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

    <form>
        <!-- Form Contents -->
    </form>
</div>

Незважаючи на те, що включений View успадкує всі дані, доступні в батьківському поданні, ви також можете передати масив додаткових даних включеному поданню:

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

Якщо ви спробуєте@includeView, яке не існує, Laravel видасть помилку. Якщо ви хочете включити View, яке може бути або не бути, вам слід скористатися@includeIfдиректива:

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

Якщо ви хотіли б@includeView, якщо заданий булевий вираз має значенняtrue, ви можете використовувати@includeWhenдиректива:

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

Якщо ви хотіли б@includeView, якщо заданий булевий вираз має значенняfalse, ви можете використовувати@includeUnlessдиректива:

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

Для включення першого View, яке існує із заданого масиву переглядів, ви можете використовуватиincludeFirstдиректива:

@includeFirst(['custom.admin', 'admin'], ['some' => 'data'])
Вам слід уникати використання__DIR__і__FILE__константи у ваших Viewх Blade, оскільки вони будуть посилатися на розташування кешованого, скомпільованого View.

Псевдонім включає

Якщо ваш 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'])

Rendering Views для колекцій

Ви можете поєднувати Loops та включення в одну лінію з Bladeми@eachдиректива:

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

Перший аргумент - це частковий вигляд, який відображається для кожного елемента масиву чи колекції. Другий аргумент - це масив або колекція, для яких ви хочете виконати ітерацію, тоді як третій аргумент - це назва змінної, яка буде присвоєна поточній ітерації у поданні. Так, наприклад, якщо ви виконуєте ітерацію по масивуjobs, як правило, ви хочете отримати доступ до кожного завдання якjobзмінна у вашому поданні часткова. Ключ поточної ітерації буде доступний якkeyзмінна у вашому поданні часткова.

Ви також можете передати четвертий аргумент@eachдиректива. Цей аргумент визначає View, яке буде відображатися, якщо даний масив порожній.

@each('view.name', $jobs, 'job', 'view.empty')
Views, надані через@eachне успадковувати змінні з батьківського View. Якщо дочірній перегляд вимагає цих змінних, вам слід скористатися@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 дозволяє вам визначити власні власні директиви за допомогоюdirectiveметод. Коли компілятор Blade зустріне користувацьку директиву, він викличе наданий зворотний виклик із виразом, який містить директива.

Наступний приклад створює a@datetime($var)директива, яка форматує даний$var, який повинен бути екземпляромDateTime:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @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 вам потрібно буде видалити всі кешовані View Blade. Кешовані види Blade можна видалити за допомогоюview:clearartisan командування.

Спеціальні Statements If

Програмування користувацької директиви іноді є складнішим, ніж це необхідно при визначенні простих, користувацьких умовних операторів. З цієї причини Blade надає aBlade::ifметод, який дозволяє швидко визначати власні умовні директиви за допомогою Closures. Наприклад, давайте визначимо спеціальний умовний, який перевіряє поточного постачальника хмарних додатків. Ми можемо зробити це вbootметод нашогоAppServiceProvider:

use Illuminate\Support\Facades\Blade;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Blade::if('cloud', function ($provider) {
        return config('filesystems.default') === $provider;
    });
}

Після того, як спеціальний умовний буде визначений, ми можемо легко використовувати його на наших шаблонах:

@cloud('digitalocean')
    // The application is using the digitalocean cloud provider...
@elsecloud('aws')
    // The application is using the aws provider...
@else
    // The application is not using the digitalocean or aws environment...
@endcloud

@unlesscloud('aws')
    // The application is not using the aws environment...
@endcloud