Chytřejší atributy přicházejí do Latte

David Grudl
Nette Core | 8284
+
+6
-

Chci představit nové možnosti, jak se vykreslují atributy v Latte, která zpohodlní práci se šablonami a učiní je více typově bezpečnými. Hlavním záměrem je vyřešit časté požadavky s vykreslováním atributů, při zachování zpětné kompatibility pro stávající kód.

Boolean v atributu

<div foo="{$val}">

Pokud je $val řetězec nebo číslo, je jasné, co se vykreslí. Co ale když $val obsahuje boolean?

<div foo="{=true}" bar="{=false}">
// vykreslí se: <div foo="1" bar="">

Což není ideální, protože podobné chování není v praxi skoro nikdy užitečné

Chci proto vydat verzi, která bude vyhazovat varování, pokud hodnota atributu je boolean (nebo pole, viz dále), že tento typ není podporován. Varování bude odkazovat přímo na jméno šablony a číslo řádku.

Výjimkou jsou boolean atributy

Boolean atributy (jako třeba checked nebo hidden) budou boolean hodnoty akceptovat. Hodnota rozhodne, jestli se atribut vykreslí nebo ne (podle toho, zda je truthy):

<input hidden="{=true}" readonly="{=false}">
// vykreslí se: <input hidden>

Tato změna chování nepředstavuje BC break, protože momentálně nedává smysl, aby někdo v šabloně kombinoval boolean atribut s jakoukoliv hodnotou.

Aria atributy

Další výjimkou by byly aria-atributy, u kterých bych chtěl boolean atributy vypisovat jako true a false, protože s těmito tvary pracují:

<button aria-expanded="{=true}" aria-checked="{=false}">
// vykreslí se: <button aria-expanded="true" aria-checked="false">

Opět mám za to, že nejde o BC break, protože momentálně nedává smysl, aby někdo v šabloně kombinoval aria atribut s bool hodnotou.

Data atributy

Možná by bylo užitečné, kdyby se data-atributy chovaly podobně jako aria-atributy, tj. aby se bool hodnoty akceptovaly a vypisovaly jako true a false. Ale to už by představovalo BC break. Tudíž data-atributy nepředstavují žádnou výjimku a budou vyhazovat varování.

Dovedu si představit, že současné chování, že se boolean přetypuje na "1" nebo "", vám u data-atributů vyhovuje, že s tím počítáte. Pak je nejjednodušší je obejít tím, že hodnotu přetypujete na string <div data-foo="{(string) $val}">. Chápu, že to případ, kdy by tato úprava znamenala nějakou práci navíc.

Pokud byste naopak chtěli jít cestou hodnot true a false, asi nejjednodušší je na vyrobit filtr. Přemýšlím, že nejaký takový doplním do standardní výbavy.

Pole v atributu

Co když se pokusíme předat do atributu pole?

<div foo="{[]}">
// vykreslí se: <div foo="Array">

V nové verzi chci kromě toho, že Latte bude vyhazovat varování, když v hodnotě atributu bude pole, aby takové atributy vůbec nevykreslilo, protože foo="Array" není nikdy užitečné.

Pole ale bude možné uvést u atributů style:

<div style={[ backgroundColor: 'lightblue', fontSize: '16px' ]}>
// vykreslí: <div style="background-color: lightblue; font-size: 16px">

Dále u atributů očekávajících seznam oddělený mezerou, jako třeba class (což vlastně z něj dělá ekvivalent n:class):

<div class={[ first: true, last: false, always ]}>
// vykreslí: <div class="first always">

A nakonec u všech data-* atributů, kde se bude serializovat jako JSON:

<div data-config={[ theme: 'dark', version: 2 ]}>
// vykreslí: <div data-config='{"theme":"dark","version":2}'>

n:attr

Cílem je také zcela sjednotit, jak se vykreslují atributy pomocí značky n:attr, s tím, jak se vykreslují když je přímo zapíšeme v kódu šablony.

Volitelné atributy

Rád bych někdy v budoucnu dospěl v flexibilnějšímu podmíněnému vykreslování atributů. Bylo by tak třeba možné snadno zapsat data-atributy, kde by hodnota rozhodla o jejich přítomnosti nebo nepřítomnosti, tedy by vlastně fungovaly jako boolean atributy.

Nicméně takže věc je složitější z pohledu kompatibility, takže na to vytvořím samostatné vlákno.