スマートな 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,
]}>押してください</button>
$isActive が真なら、次のように出力されます。
<button class="btn btn-primary active">押してください</button>
この振る舞いは class
に限りません。空白区切りの値のリストを期待する一連の属性、すなわち
accesskey、class、headers、itemprop、ping、rel、role、sandbox、そしてすべての
aria-*
属性で機能します。それ以外の属性に配列を渡すと警告が出て、値は捨てられます。
<a rel={[nofollow, noopener, external => $isExternal]}>リンク</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 属性
JavaScript 向けの設定を HTML に渡したいことはよくあります。以前は json_encode
を使っていました。今は配列や stdClass オブジェクトを data- 属性に渡すだけで、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 への移行をご覧ください。
