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,
]}>押してください</button>
```

`$isActive` が真なら、次のように出力されます。

```latte
<button class="btn btn-primary active">押してください</button>
```

この振る舞いは `class` に限りません。空白区切りの値のリストを期待する一連の属性、すなわち `accesskey`、`class`、`headers`、`itemprop`、`ping`、`rel`、`role`、`sandbox`、そしてすべての `aria-*` 属性で機能します。それ以外の属性に配列を渡すと警告が出て、値は捨てられます。

```latte
<a rel={[nofollow, noopener, external => $isExternal]}>リンク</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 属性
=========

JavaScript 向けの設定を HTML に渡したいことはよくあります。以前は `json_encode` を使っていました。今は配列や stdClass オブジェクトを `data-` 属性に渡すだけで、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 には checkeddisabledselectedhidden のような特別な属性があり、具体的な値は意味を持たず、存在するかどうかだけが問われます。単純なフラグとして働くわけです。

Latte はこれらを自動的に扱います。属性には任意の式を渡せます。真であれば属性が出力され、偽(falsenull0、空文字列など)であれば属性はまるごと省かれます。

つまり、面倒な条件分岐や n:attr とはお別れして、単にこう書けます。

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

$isDisabledfalse$isReadOnlytrue なら、次のように出力されます。

<input type="text" readonly>

この自動処理を持たない標準の属性(data-aria- 属性など)で同じ切り替えをしたい場合は、toggle フィルタを使ってください。

null 値

これは最も嬉しい変更のひとつです。以前は変数が null のとき、空文字列 "" として出力されていました。そのため HTML に class=""title="" のような空の属性が現れがちでした。

Latte 3.1 では新しい統一ルールが適用されます。値が null なら、その属性は存在しない。

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

$titlenull なら出力は <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 に限りません。空白区切りの値のリストを期待する一連の属性、すなわち accesskeyclassheadersitemproppingrelrolesandbox、そしてすべての aria-* 属性で機能します。それ以外の属性に配列を渡すと警告が出て、値は捨てられます。

<a rel={[nofollow, noopener, external => $isExternal]}>リンク</a>

スタイル

style 属性も配列に対応しています。条件付きのスタイルに特に便利です。配列の項目がキー(CSS プロパティ)と値を持つ場合、値が nullfalse0、空文字列のときはそのプロパティが省かれます。たとえば 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>

さらに truefalse は文字列 "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 はどの属性がどういう種類で、どんな値を期待するかを知っています。

  • 標準の属性hrefidvalueplaceholder など)は、テキストとして出力できる値を期待します。文字列、数値、文字列化できるオブジェクトが該当します。null も受け付けます(属性が消えます)。ただし、うっかり配列や真偽値、一般的なオブジェクトを渡すと、Latte は警告を出し、その不正な値を賢く無視します。
  • 真偽値属性checkeddisabled など)は、存在の有無が真偽で決まるため、どんな型でも受け付けます。
  • スマート属性classstyledata- など)は、配列を正しい入力として特別に扱います。

このチェックにより、アプリケーションが思いがけない HTML を出力しなくなります。

Latte 3.0 からの移行

null の振る舞い(以前は "" を出力、現在は属性を削除)と data- 属性(以前は真偽値が "1"/""、現在は "true"/"false")が変わったため、テンプレートの更新が必要になることがあります。

スムーズに移行できるよう、Latte には違いを示す移行モードが用意されています。詳しくは Latte 3.0 から 3.1 への移行をご覧ください。