Nette Documentation Preview

syntax
Умные HTML-атрибуты
*******************

.[perex]
Latte 3.1 приносит набор улучшений, посвящённых одному из самых частых занятий в шаблонах - выводу HTML-атрибутов. Он даёт больше удобства, гибкости и безопасности.


Логические атрибуты
===================

В HTML есть особые атрибуты, такие как `checked`, `disabled`, `selected` или `hidden`, у которых конкретное значение не важно: важно лишь их наличие. Они работают как простые флаги.

Latte обрабатывает их автоматически. В атрибут можно передать любое выражение. Если оно истинно, атрибут отрисовывается. Если ложно (например, `false`, `null`, `0` или пустая строка), атрибут полностью опускается.

Это значит, что вы можете распрощаться с громоздкими условиями и `n:attr` и просто написать:

```latte
<input type="text" disabled={$isDisabled} readonly={$isReadOnly}>
```

Если `$isDisabled` равно `false`, а `$isReadOnly` равно `true`, отрисуется:

```latte
<input type="text" readonly>
```

Если вам нужно такое переключение для обычных атрибутов, у которых нет автоматической обработки (например, для атрибутов `data-` или `aria-`), используйте фильтр [toggle |filters#toggle].


Значения null
=============

Это одно из самых приятных изменений. Раньше, если переменная была `null`, она выводилась как пустая строка `""`. Это часто приводило к пустым атрибутам в HTML вроде `class=""` или `title=""`.

В Latte 3.1 действует новое универсальное правило: **значение `null` означает, что атрибута нет.**

```latte
<div title="{$title}"></div>
```

Если `$title` равно `null`, вывод будет `<div></div>`. Если в нём строка, например "Hello", вывод будет `<div title="Hello"></div>`. Благодаря этому вам не нужно оборачивать атрибуты в условия. Это правило действует, когда всё значение атрибута состоит из одного выражения `{...}`; в смешанном значении вроде `title="foo {$bar}"` значение `null` отрисуется как пустая строка.

Если вы используете фильтры, помните, что они обычно преобразуют `null` в строку (например, в пустую). Чтобы этого не происходило, используйте [nullsafe-фильтр |filters#Nullsafe-фильтры] `?|`:

```latte
<div title="{$title?|upper}"></div>
```


Классы
======

В атрибут `class` можно передать массив. Это идеально подходит для условных классов: если массив ассоциативный, ключи используются как имена классов, а значения как условия. Класс отрисуется только тогда, когда условие истинно.

```latte
<button class={[
	btn,
	btn-primary,
	active => $isActive,
]}>Press me</button>
```

Если `$isActive` истинно, отрисуется:

```latte
<button class="btn btn-primary active">Press me</button>
```

Это поведение не ограничивается атрибутом `class`. Оно работает для избранного набора атрибутов, которые ожидают список значений через пробел: `accesskey`, `class`, `headers`, `itemprop`, `ping`, `rel`, `role`, `sandbox` и все атрибуты `aria-*`. Для любого другого атрибута передача массива вызовет предупреждение, а значение будет отброшено.

```latte
<a rel={[nofollow, noopener, external => $isExternal]}>link</a>
```


Стили
=====

Атрибут `style` тоже поддерживает массивы. Особенно это удобно для условных стилей. Если элемент массива содержит ключ (CSS-свойство) и значение, свойство опускается, когда значение равно `null`, `false`, `0` или пустой строке, поэтому, например, `opacity => 0` не отрисуется.

```latte
<div style={[
	background => lightblue,
	display => $isVisible ? block : null,
	font-size => '16px',
]}></div>
```

Если `$isVisible` ложно, отрисуется:

```latte
<div style="background: lightblue; font-size: 16px"></div>
```


Атрибуты data
=============

Часто нам нужно передать в HTML конфигурацию для JavaScript. Раньше это делалось через `json_encode`. Теперь вы можете просто передать в атрибут `data-` массив или объект stdClass, и Latte сериализует его в JSON:

```latte
<div data-config={[ theme: dark, version: 2 ]}></div>
```

Выводит:

```latte
<div data-config='{"theme":"dark","version":2}'></div>
```

Кроме того, `true` и `false` отрисовываются как строки `"true"` и `"false"` (то есть как корректный JSON).


Атрибуты aria
=============

Спецификация WAI-ARIA требует для логических значений текстовые значения `"true"` и `"false"`. Latte делает это для атрибутов `aria-` автоматически:

```latte
<button aria-expanded={=true} aria-checked={=false}></button>
```

Выводит:

```latte
<button aria-expanded="true" aria-checked="false"></button>
```

Точно так же, как `class`, атрибуты `aria-` принимают и массив. Он трактуется как список через пробел: обычные значения используются как есть, а ключ попадает в вывод только тогда, когда его значение равно `true`:

```latte
<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|cookbook/migration-from-latte-30].

[* html-attributes.webp *]

Умные 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.