Умные HTML-атрибуты
Latte 3.1 приносит набор улучшений, посвящённых одному из самых частых занятий в шаблонах – выводу HTML-атрибутов. Он даёт больше удобства, гибкости и безопасности.
Логические атрибуты
В HTML есть особые атрибуты, такие как checked, disabled,
selected или hidden, у которых конкретное значение не важно:
важно лишь их наличие. Они работают как простые флаги.
Latte обрабатывает их автоматически. В атрибут можно передать любое
выражение. Если оно истинно, атрибут отрисовывается. Если ложно
(например, false, null, 0 или пустая строка), атрибут
полностью опускается.
Это значит, что вы можете распрощаться с громоздкими условиями и
n:attr и просто написать:
<input type="text" disabled={$isDisabled} readonly={$isReadOnly}>
Если $isDisabled равно false, а $isReadOnly равно true,
отрисуется:
<input type="text" readonly>
Если вам нужно такое переключение для обычных атрибутов, у которых
нет автоматической обработки (например, для атрибутов data- или
aria-), используйте фильтр toggle.
Значения null
Это одно из самых приятных изменений. Раньше, если переменная была
null, она выводилась как пустая строка "". Это часто
приводило к пустым атрибутам в HTML вроде class="" или title="".
В Latte 3.1 действует новое универсальное правило: значение null
означает, что атрибута нет.
<div title="{$title}"></div>
Если $title равно null, вывод будет <div></div>. Если
в нём строка, например “Hello”, вывод будет <div title="Hello"></div>.
Благодаря этому вам не нужно оборачивать атрибуты в условия. Это
правило действует, когда всё значение атрибута состоит из одного
выражения {...}; в смешанном значении вроде title="foo {$bar}"
значение null отрисуется как пустая строка.
Если вы используете фильтры, помните, что они обычно преобразуют
null в строку (например, в пустую). Чтобы этого не происходило,
используйте nullsafe-фильтр
?|:
<div title="{$title?|upper}"></div>
Классы
В атрибут class можно передать массив. Это идеально подходит для
условных классов: если массив ассоциативный, ключи используются как
имена классов, а значения как условия. Класс отрисуется только тогда,
когда условие истинно.
<button class={[
btn,
btn-primary,
active => $isActive,
]}>Press me</button>
Если $isActive истинно, отрисуется:
<button class="btn btn-primary active">Press me</button>
Это поведение не ограничивается атрибутом class. Оно работает
для избранного набора атрибутов, которые ожидают список значений
через пробел: accesskey, class, headers, itemprop,
ping, rel, role, sandbox и все атрибуты aria-*.
Для любого другого атрибута передача массива вызовет предупреждение,
а значение будет отброшено.
<a rel={[nofollow, noopener, external => $isExternal]}>link</a>
Стили
Атрибут style тоже поддерживает массивы. Особенно это удобно для
условных стилей. Если элемент массива содержит ключ (CSS-свойство) и
значение, свойство опускается, когда значение равно null,
false, 0 или пустой строке, поэтому, например,
opacity => 0 не отрисуется.
<div style={[
background => lightblue,
display => $isVisible ? block : null,
font-size => '16px',
]}></div>
Если $isVisible ложно, отрисуется:
<div style="background: lightblue; font-size: 16px"></div>
Атрибуты data
Часто нам нужно передать в HTML конфигурацию для JavaScript. Раньше это
делалось через json_encode. Теперь вы можете просто передать в
атрибут data- массив или объект stdClass, и Latte сериализует его в JSON:
<div data-config={[ theme: dark, version: 2 ]}></div>
Выводит:
<div data-config='{"theme":"dark","version":2}'></div>
Кроме того, true и false отрисовываются как строки
"true" и "false" (то есть как корректный JSON).
Атрибуты aria
Спецификация WAI-ARIA требует для логических значений текстовые
значения "true" и "false". Latte делает это для атрибутов
aria- автоматически:
<button aria-expanded={=true} aria-checked={=false}></button>
Выводит:
<button aria-expanded="true" aria-checked="false"></button>
Точно так же, как class, атрибуты aria- принимают и массив. Он
трактуется как список через пробел: обычные значения используются как
есть, а ключ попадает в вывод только тогда, когда его значение равно
true:
<span aria-labelledby={[title, description => $hasDescription]}></span>
Проверка типов
Вы когда-нибудь видели в сгенерированном HTML <input value="Array">?
Это классическая ошибка, которая часто остаётся незамеченной. Latte
вводит строгую проверку типов для HTML-атрибутов, чтобы ваши шаблоны
лучше сопротивлялись подобным недосмотрам.
Latte знает, какой атрибут к какому виду относится и какие значения он ожидает:
- Обычные атрибуты (такие как
href,id,value,placeholder…) ожидают значение, которое можно отрисовать как текст. Сюда относятся строки, числа или объекты, приводимые к строке. Принимается иnull(он опускает атрибут). Но если вы по ошибке передадите массив, логическое значение или произвольный объект, Latte выдаст предупреждение и разумно проигнорирует некорректное значение. - Логические атрибуты (такие как
checked,disabled…) принимают любой тип, потому что их наличие определяется истинностью значения. - Умные атрибуты (такие как
class,style,data-…) специально обрабатывают массивы как корректный ввод.
Эта проверка гарантирует, что ваше приложение не выдаст неожиданный HTML.
Миграция с Latte 3.0
Поскольку поведение null (раньше выводилось "", теперь
атрибут опускается) и атрибутов data- (логические значения раньше
выводились как "1"/"", теперь как "true"/"false")
изменилось, вам может понадобиться обновить шаблоны.
Для плавного перехода Latte предлагает режим миграции, который подсвечивает различия. Прочитайте подробное руководство Миграция с Latte 3.0 на 3.1.
