Laravel blade. 11 мало используемых директив

17 July 2019
#Laravel#PHP

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

@forelse

Что бы не писать лишний if воспользуйтесь директивой @forelse

Что обычно пишут:

@if ($users->count() > 0)
    @foreach($users as $user)
        {{ $user->name }}
    @endforeach
@else
    <p>Пользователи отсутствуют</p>
@endif

Можно преобразовать к такому виду:

@forelse($users as $user)
    {{ $user->name }}
@empty
    <p>Пользователи отсутствуют</p>
@endforelse

По сути тот же foreach к которому добавили @empty.

Такая конструкция выведет указанное содержимое, если был передан пустой массив.

Первый вариант несколько гибче, второй быстрее (в плане написания) и более читаем.

@unless

unless - if с логическим отрицанием. Если вы работаете с Ruby, то эта конструкция вам должна быть привычна.

Вместо:

@if (!$badUser)
    <p>{{ $user->fullName }}</p>
@endif

Попробуйте использовать:

@unless($badUser)
    <p>{{ $user->fullName }}</p>
@endunless

@each

На мой взгляд очень удобная директива, если нужно подключить какой-то шаблон в цикле.

Что обычно пишут:

@foreach($users as $user)
    @include('users.details', ['user' => $user])
@endforeach

Как упростить:

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

Первый аргумент - путь.имя шаблона.

Второй - массив по которому будет крутиться цикл

Третий - имя в шаблоне

Вариант с четвёртым аргументом:

@each('users.details', $users, 'user', 'users.notfound')

Думаю тут всё и так видно, но на всякий случай скажу, что четвёртый аргумент - шаблон который будет использоваться если массив $users пустой

@json

Эта директива - сокращение записи с json_encode.

Обычно пишут:

<script>
    let users = {!! json_encode($users)!!};
</script>

Преобразуем в:

<script>
    let users = @json($users);
</script>

@verbatim

В переводе "дословный", используется для того, что бы не ставить @ перед каждым оператором вывода в блоке. Вы ведь помните для чего нужна собачка перед скобками? =)

Как обычно пишут:

<div class="col-xs-12">
    Hello, @{{ world }}
    Hi, @{{ name }}
</div>

Так можно упростить:

@verbatim
    <div class="col-xs-12">
        Hello, {{ world }}
        Hi, {{ name }}
    </div>
@endverbatim

@isset & @empty

Тут уж совсем всё просто. Эти директивы аналогичны одноименным в PHP. Если вы посмотрите (рекомендую смотреть в исходники фреймворков чаще) Illuminate/View/Compilers/Concerns/CompilesConditionals.php то найдёт там, что то вроде такого:

/**
    * Compile the if-isset statements into valid PHP.
    *
    * @param  string  $expression
    * @return string
    */
protected function compileIsset($expression)
{
    return "<?php if(isset{$expression}): ?>";
}

И конечно же нет смысла делать так:

@if (isset($myString))
    // ...
@endif

@if (empty($myString))
    // ...
@endif

Лучше воспользоваться директивами:

@isset($myString)
    // ...
@endisset

@empty($myString)
    // ...
@endempty

@hasSection

Вы так же можете проверить наличие какого-либо контента в секции используя директиву @hasSection hasSection проверяет наличие контента в секции. Закрывать следует директивой endif

К примеру:

@hasSection('navbar')
    <nav class="navbar navbar-light bg-light">
        @yield('navbar')
    </nav>
@endif

@php

Использование этой директивы может показаться сомнительно. Решать вам. Мне к примеру приятно работать в едином стиле.

Лёгкой рукой заменяем:

<?php
    $summ = $left + right;
?>

На:

@php
    $summ = $left + right;
@endphp

@csrf && @method

Напомню, что с приходом 5.6 больше не нужно использовать csrffield и methodfield так как появились похожие директивы.

Было:

<form method="POST">
    {{ csrf_field()}}
    {{ method_field("DELETE")}}
    <!--  ...  -->
</form>

Стало:

<form method="POST">
    @csrf
    @method("DELETE")
    <!-- ... -->
</form>

@inject

Для внедрения сервисов в шаблон вы можете использовать директиву @inject

Пример:

@inject('details', 'App\Services\NameAndRole')

<div>
    {{ $details->username }}
    {{ $details->sullName }}
</div>

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

@includeWhen

includeWhen это упрощение конструкции if - include:

@if($showUsers)
    @include('users.all', ['users' => $users])
@endif

Если первый аргумент true то инклюдит view указанный во втором аргументе и передаёт ему данные из третьего

@includeWhen($showUsers, 'users.all', ['users' => $users])

На этом всё. Спасибо за внимание!