Что касается моей работы с HTML и PHP, то чаще всего я работаю со списками (select). Кто не помнит, то это тег, отображающий выпадающий список с возможностью выбора пунктов.
<select id="category-list"> <option value="sports">Sports</option> <option value="politics">Politics</option> <option value="entertainment">Entertainment</option> <option value="technology">Technology</option> </select>
Обычный безвредный код. Давайте лучше посмотрим на пример из реальной жизни, чтобы понять, с чем я обычно сталкиваюсь.
Редактирование Podcast
Когда один из редакторов решает отредактировать подкаст, то ему показывается HTML-форма с кучей input’ов. Каждый из них заполняется свойствами подкаста, такими как title
, abstract
, tags
и category.
Category
выбирается из списка, кодом, который я показал выше. Например, подкаст может принадлежать к категории «Спорт». Это позволит подкасту появляться на сайте в разделе «Спорт».
Как нам теперь взять подкаст и показать выбранную опцию, соответствующую категории подкаста? Blade может нам помочь в этом:
<select id="category-list"> <option value="sports" @if($article->category === 'sports') selected @endif> Sports</option> <option value="politics" @if($article->category === 'politics') selected @endif> Politics</option> <option value="entertainment" @if($article->category === 'entertainment') selected @endif> Entertainment</option> <option value="technology" @if($article->category === 'technology') selected @endif> Technology</option> </select>
Как вы видите, наш код стал многословным и затрудненным для понимания. Похоже, здесь есть работа для директивы!
Директива selectedWhen
Наша новая blade-директива будет отвечать за две вещи: вывод value
и добавление свойства selected
, если значение равно тому, что мы передаем. Итак, эта директива будет принимать два аргумента.
Работа с аргументами в директиве Blade довольно сложна.Я имею в виду, функция директивы получит только один параметр в виде строки. Если вы захотите разделить параметры, то вам придется сделать это командой explode
. Хорошо, сначала давайте подумаем о том, что мы хотим получить в итоге:
<select id="category-list"> <option @selectedWhen('sports', $article->category)> Sports</option> <option @selectedWhen('politics', $article->category)> Politics</option> <option @selectedWhen('entertainment', $article->category)> Entertainment</option> <option @selectedWhen('technology', $article->category)> Technology</option> </select>
Хорошо, директива будет очень простой: мы выдаем значение, затем сравниваемое значение, и все. Значение будет напечатано в любом случае, но, если оба значения равны, то в опцию добавится selected
.
Теперь нужно создать директиву.
Создание директивы
Для начала очистим скомпилированные шаблоны командой php artisan view:clear
Дело в том, что каждый раз, когда блейд-шаблон компилируется, он кэшируется как чистый php-код в хранилище вашего приложения. Если вы что-то измените в шаблоне, то он будет скомпилирован снова. А если вы измените код директивы, то не будет, ведь шаблоны не менялись. Поэтому очистка кэша скомпилированных шаблонов обязательна при каждом изменении кода директив.
Давайте перейдем в AppServiceProvider@boot
и зарегистрируем директиву:
Blade::directive('selectedWhen', function ($parameters) { dd($parameters); // От этого избавимся позже });
После использования нашей директивы где-нибудь в шаблоне, давайте зайдем по его адресу. Мы получим дамп параметров, который будет выглядеть так:
"'sports', $article->category"
Как видите, двойные кавычки означают, что директива получила строку, а не массив из нескольких параметров. Мы можем просто разобрать (explode
) строку на параметры.
Blade::directive('selectedWhen', function ($parameters) { [$value, $expected] = explode(',', $parameters); dd([$value, $expected]); });
Теперь получим:
[ 0 => "'sports'", 1 => " $article->category" ]
Нужно убрать одинарные кавычки из первого параметра. Можно использовать для этого удобный метод trim()
и повторно объявить переменную после разделения. Если вы используете в качестве первого параметра строку без кавычек, то нет проблем, будут обрезаться только кавычки.
После этого нам нужно только вернуть строку с php-кодом, чтобы ее можно было скомпилировать с полученными переменными. Эта строка затем копируется в скомпилированный шаблон, который позже выполнит PHP.
Blade::directive('selectedWhen', function ($parameters) { [$value, $expected] = explode(',', $parameters); $value = trim($value, '\''); return "value=\"$value\" <?php if ('$value' === $expected) { echo 'selected'; }"; });
Вот и все. В следующий раз, когда вам придется вывести множество списков, то вам не нужно будет подробно их расписывать. Хорошая директива вам поможет с этим.
Автор: Italo Baeza
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.