Nette Documentation Preview

syntax
構文
***

.[perex]
Latte の構文は、ウェブデザイナーの実務上の要求から生まれました。ふつうならかなり厄介な構造をきれいに書ける、最も使いやすい構文を探し求めた結果です。同時に、式はすべて PHP とまったく同じ書き方なので、新しい言語を覚える必要はありません。すでに知っていることをそのまま活かせます。

以下は、タグ、n:属性、コメント、フィルタという基本要素をいくつか示す最小限のテンプレートです。

```latte
{* これはコメントです *}
<ul n:if=$items>                  {* n:if は n:属性です *}
{foreach $items as $item}         {* foreach ループを表すタグ *}
	<li>{$item|capitalize}</li>   {* フィルタを通して変数を出力するタグ *}
{/foreach}                        {* ループの終わり *}
</ul>
```

これらの大切な要素と、それがどうやって素晴らしいテンプレートづくりを助けてくれるのかを、もう少し詳しく見ていきましょう。


タグ
===

テンプレートには、テンプレートのロジックを制御する(*foreach* ループなど)タグや、式を出力するタグが含まれます。どちらにも同じ区切り `{ ... }` を使うので、ほかのシステムと違って、どの場面でどの区切りを使うか考える必要がありません。`{` の直後に空白、引用符、もうひとつの `{` や `}` が続く場合、Latte はそれをタグの始まりとみなさないので、JavaScript の構文、JSON、CSS の規則をテンプレートで問題なく使えます。

[すべてのタグの一覧|tags]をご覧ください。さらに、独自の[カスタムタグ|custom-tags]を作ることもできます。`{ }` の区切りを変えたり、まるごと無効にしたり(`{syntax double}`、`{syntax off}`、`n:syntax` 属性を使います)もできます。[構文の変更 |tags#{syntax}]をご覧ください。


Latte は PHP を理解する
=================

タグの中では、見慣れた PHP の式が使えます。

- 変数
- 文字列(HEREDOC と NOWDOC を含む)、配列、数値など
- [演算子 |https://www.php.net/manual/en/language.operators.php]
- 関数やメソッドの呼び出し([サンドボックス|sandbox]で制限できます)
- [match |https://www.php.net/manual/en/control-structures.match.php]
- [アロー関数 |https://www.php.net/manual/en/functions.arrow.php]
- [ファーストクラス callable 構文 |https://www.php.net/manual/en/functions.first_class_callable_syntax.php]
- 複数行コメント `/* ... */`
- など…

さらに Latte は、いくつかの[便利な拡張 |#シンタックスシュガー]で PHP の構文を強化しています。


n:属性
====

`{if} … {/if}` のように、ひとつの HTML 要素に対して働くペアタグはすべて、n:属性の形に書き換えられます。たとえば冒頭の例の `{foreach}` は、次のようにも書けます。

```latte
<ul n:if=$items>
	<li n:foreach="$items as $item">{$item|capitalize}</li>
</ul>
```

すると、その機能は属性が置かれた HTML 要素に適用されます。

```latte
{var $items = ['I', '♥', 'Latte']}

<p n:foreach="$items as $item">{$item}</p>
```

出力:

```latte
<p>I</p>
<p>♥</p>
<p>Latte</p>
```

`inner-` 接頭辞を使うと、要素の内側だけに適用されるように振る舞いを変えられます。

```latte
<div n:inner-foreach="$items as $item">
	<p>{$item}</p>
	<hr>
</div>
```

出力:

```latte
<div>
	<p>I</p>
	<hr>
	<p>♥</p>
	<hr>
	<p>Latte</p>
	<hr>
</div>
```

`tag-` 接頭辞を使えば、HTML タグそのものにだけ機能を適用できます。

```latte
<p><a href={$url} n:tag-if="$url">タイトル</a></p>
```

これは変数 `$url` に応じて次のように出力します。

```latte
{* $url が空のとき *}
<p>タイトル</p>

{* $url が 'https://nette.org' のとき *}
<p><a href="https://nette.org">タイトル</a></p>
```

とはいえ n:属性はペアタグの略記だけではありません。純粋な n:属性もあります。たとえばコーダーの親友 [n:class|tags#n:class] や、とても便利な [n:href |application:creating-links#プレゼンターのテンプレートで] です。

引用符を使う `<div n:if="$foo">` という書き方に加えて、波かっこを使う `<div n:if={$foo}>` という書き方もできます。主な利点は、`{...}` の中で単引用符と二重引用符の両方を自由に使えることです。

```latte
<div n:if={str_contains($val, "foo")}> ... </div>
```


スマートな HTML 属性 .{data-version:3.1.0}
===================================

Latte は標準の HTML 属性の扱いを驚くほど簡単にします。`checked` のような真偽値属性を面倒みてくれ、`null` を含む属性を取り除き、`class` や `style` の値を配列で組み立てられるようにします。`data-` 属性のデータは JSON に自動でシリアライズまでしてくれます。

```latte
{* null は属性を取り除きます *}
<div title={$title}>

{* 真偽値が真偽値属性の有無を制御します *}
<input type="checkbox" checked={$isChecked}>

{* class では配列が使えます *}
<div class={['btn', 'btn-primary', active => $isActive]}>

{* data- 属性では配列が JSON にエンコードされます *}
<div data-config={[theme: dark, version: 2]}>
```

詳しくは別の章[スマートな HTML 属性|html-attributes]をご覧ください。


フィルタ
====

[標準フィルタ |filters]の一覧をご覧ください。

フィルタはパイプ記号のあとに書きます(前に空白があってもかまいません)。

```latte
<h1>{$heading|upper}</h1>
```

フィルタは連ねられ、左から右の順に適用されます。

```latte
<h1>{$heading|lower|capitalize}</h1>
```

引数はフィルタ名のあとにコロンで続け、さらに引数があればカンマで区切ります。かっこを使った呼び出しもできます。

```latte
<h1>{$heading|truncate:20,''}</h1>
<h1>{$heading|truncate(20, '')}</h1>
```

フィルタは式に対しても適用できます。

```latte
{var $name = ($title|upper) . ($subtitle|lower)}
```

ブロックに対しても。

```latte
<h1>{block |lower}{$heading}{/block}</h1>
```

値に直接適用することもできます([`{=expr}` |tags#出力] タグとの組み合わせ)。

```latte
<h1>{='  Hello world  '|trim}</h1>
```

値が `null` になり得て、その場合はフィルタを適用したくないなら、[nullsafe フィルタ |filters#nullsafe フィルタ] `?|` を使います。

```latte
<h1>{$heading?|upper}</h1>
```


動的 HTML タグ .{data-version:3.0.9}
================================

Latte は動的な HTML タグに対応しています。タグ名に柔軟さが必要なときに便利です。

```latte
<h{$level}>見出し</h{$level}>
```

たとえば上のコードは、変数 `$level` の値に応じて `<h1>見出し</h1>` や `<h2>見出し</h2>` を生成できます。Latte の動的 HTML タグは常にペアでなければなりません。代わりの手段は [n:tag |tags#n:tag] です。

Latte は安全なテンプレートシステムなので、できあがるタグ名が正しいこと、望ましくない値や悪意ある値を含まないことを確認します。また、終了タグの名前が常に開始タグの名前と一致するようにします。


コメント
====

コメントは次のように書き、出力には現れません。

```latte
{* これは Latte のコメントです *}
```

タグの中では PHP のコメントが使えます。

```latte
{include 'file.info', /* value: 123 */}
```


空白の制御
=====

Latte は空白を賢く扱います。読みやすさのために自由にインデントしても、出力はきれいなままです。制御タグが行にひとつだけある場合、その行全体(インデントと改行)が出力から取り除かれます(`{$var}`、`{=...}`、`{_...}` のように出力を行うタグには当てはまらず、そのインデントと末尾の改行は保たれます)。

```latte
<ul>
	{foreach $items as $item}
	<li>{$item}</li>
	{/foreach}
</ul>
```

出力:

```latte
<ul>
	<li>foo</li>
	<li>bar</li>
</ul>
```

タグが行にひとつだけではなく、ほかの内容と並んでいる場合はどうでしょうか。タグの前の空白は、タグの*内側*に属します。

```latte
<div>
	{if $foo}hello{/if}
</div>
```

インデントは実質的に `{if}` の内側にあります。`$foo` が偽なら何も出力されず、インデントも空行も残りません。`$foo` が真なら、出力には自然にインデントが含まれます。整った構造のテンプレートを書くだけで、出力は常にきれいになります。

さらにきれいな出力がほしいときは、[Dedent |develop#Dedent]機能を有効にできます。これは `{if}` や `{foreach}` のようなペアタグの入れ子によって生じるインデントも取り除きます。


シンタックスシュガー
==========


引用符のない文字列
---------

単純な文字列では引用符を省けます。

```latte
PHP と同じ: {var $arr = ['hello', 'btn--default', '€']}

短縮形:     {var $arr = [hello, btn--default, €]}
```

単純な文字列とは、英字、数字、アンダースコア、ハイフン、ピリオドだけで構成されたものです。数字で始まってはならず、ハイフンで始まったり終わったりしてもいけません。大文字とアンダースコアだけで構成されていると定数(`PHP_VERSION` など)とみなされるので、それも避けます。また、次のキーワードと衝突してはいけません: `and`、`array`、`clone`、`default`、`false`、`in`、`instanceof`、`new`、`null`、`or`、`return`、`true`、`xor`。


定数
---

グローバル定数と単純な文字列を区別するには、グローバル名前空間の区切りを使います。

```latte
{if \PROJECT_ID === 1} ... {/if}
```

この書き方は PHP 自体でもまったく正しく、バックスラッシュはその定数がグローバル名前空間にあることを示します。


短縮三項演算子
-------

三項演算子の 3 つめの値が空なら、省略できます。

```latte
PHP と同じ: {$stock ? '在庫あり' : ''}

短縮形:     {$stock ? '在庫あり'}
```


配列のキーの現代的な書き方
-------------

配列のキーは、関数呼び出しの名前付き引数と同じように書けます。

```latte
PHP と同じ: {var $arr = ['one' => 'item 1', 'two' => 'item 2']}

現代的:     {var $arr = [one: 'item 1', two: 'item 2']}
```


フィルタ
----

フィルタは任意の式に使えます。式全体をかっこで囲むだけです。

```latte
{var $content = ($text|truncate: 30|upper)}
```


`in` 演算子
--------

`in` 演算子は `in_array()` 関数の代わりになります。比較は常に厳密です。

```latte
{* in_array($item, $items, true) と同じ *}
{if $item in $items}
	...
{/if}
```


歴史をのぞく窓
-------

Latte はその歴史の中で、数年後に PHP 自体に登場することになるシンタックスシュガーをいくつも先取りしてきました。たとえば Latte では、PHP で可能になるずっと前から `array(1, 2, 3)` の代わりに `[1, 2, 3]` と書けましたし、nullsafe 演算子 `$obj?->foo` も使えました。今の PHP の `...$arr` 演算子にあたる配列展開演算子 `(expand) $arr` も、Latte が先に導入したものです。


Latte における PHP の制限
==================

Latte には PHP の式しか書けません。つまりセミコロンで終わる文は使えません。クラスの宣言もできませんし、`if`、`foreach`、`switch`、`return`、`try`、`throw` などの[制御構造 |https://www.php.net/manual/en/language.control-structures.php]も使えません。それらには Latte が[タグ|tags]を用意しています。[属性 |https://www.php.net/manual/en/language.attributes.php]、[バッククォート |https://www.php.net/manual/en/language.operators.execution.php]、一部の[マジック定数 |https://www.php.net/manual/en/language.constants.magic.php]も使えません。`unset`、`echo`、`include`、`require`、`exit`、`eval` も使えません。これらは関数ではなく PHP の特別な言語構造であり、式ではないからです。コメントは複数行の `/* ... */` だけがサポートされます。

とはいえ、[RawPhpExtension |develop#RawPhpExtension] 拡張を有効にすればこの制限を回避でき、テンプレート作者の責任のもとで `{php ...}` タグの中に任意の PHP コードを書けます。

構文

Latte の構文は、ウェブデザイナーの実務上の要求から生まれました。ふつうならかなり厄介な構造をきれいに書ける、最も使いやすい構文を探し求めた結果です。同時に、式はすべて PHP とまったく同じ書き方なので、新しい言語を覚える必要はありません。すでに知っていることをそのまま活かせます。

以下は、タグ、n:属性、コメント、フィルタという基本要素をいくつか示す最小限のテンプレートです。

{* これはコメントです *}
<ul n:if=$items>                  {* n:if は n:属性です *}
{foreach $items as $item}         {* foreach ループを表すタグ *}
	<li>{$item|capitalize}</li>   {* フィルタを通して変数を出力するタグ *}
{/foreach}                        {* ループの終わり *}
</ul>

これらの大切な要素と、それがどうやって素晴らしいテンプレートづくりを助けてくれるのかを、もう少し詳しく見ていきましょう。

タグ

テンプレートには、テンプレートのロジックを制御する(foreach ループなど)タグや、式を出力するタグが含まれます。どちらにも同じ区切り { ... } を使うので、ほかのシステムと違って、どの場面でどの区切りを使うか考える必要がありません。{ の直後に空白、引用符、もうひとつの { や } が続く場合、Latte はそれをタグの始まりとみなさないので、JavaScript の構文、JSON、CSS の規則をテンプレートで問題なく使えます。

すべてのタグの一覧をご覧ください。さらに、独自のカスタムタグを作ることもできます。{ } の区切りを変えたり、まるごと無効にしたり({syntax double}、{syntax off}、n:syntax 属性を使います)もできます。構文の変更をご覧ください。

Latte は PHP を理解する

タグの中では、見慣れた PHP の式が使えます。

さらに Latte は、いくつかの便利な拡張で PHP の構文を強化しています。

n:属性

{if} … {/if} のように、ひとつの HTML 要素に対して働くペアタグはすべて、n:属性の形に書き換えられます。たとえば冒頭の例の {foreach} は、次のようにも書けます。

<ul n:if=$items>
	<li n:foreach="$items as $item">{$item|capitalize}</li>
</ul>

すると、その機能は属性が置かれた HTML 要素に適用されます。

{var $items = ['I', '♥', 'Latte']}

<p n:foreach="$items as $item">{$item}</p>

出力:

<p>I</p>
<p>♥</p>
<p>Latte</p>

inner- 接頭辞を使うと、要素の内側だけに適用されるように振る舞いを変えられます。

<div n:inner-foreach="$items as $item">
	<p>{$item}</p>
	<hr>
</div>

出力:

<div>
	<p>I</p>
	<hr>
	<p>♥</p>
	<hr>
	<p>Latte</p>
	<hr>
</div>

tag- 接頭辞を使えば、HTML タグそのものにだけ機能を適用できます。

<p><a href={$url} n:tag-if="$url">タイトル</a></p>

これは変数 $url に応じて次のように出力します。

{* $url が空のとき *}
<p>タイトル</p>

{* $url が 'https://nette.org' のとき *}
<p><a href="https://nette.org">タイトル</a></p>

とはいえ n:属性はペアタグの略記だけではありません。純粋な n:属性もあります。たとえばコーダーの親友 n:class や、とても便利な n:href です。

引用符を使う <div n:if="$foo"> という書き方に加えて、波かっこを使う <div n:if={$foo}> という書き方もできます。主な利点は、{...} の中で単引用符と二重引用符の両方を自由に使えることです。

<div n:if={str_contains($val, "foo")}> ... </div>

スマートな HTML 属性

Latte は標準の HTML 属性の扱いを驚くほど簡単にします。checked のような真偽値属性を面倒みてくれ、null を含む属性を取り除き、class や style の値を配列で組み立てられるようにします。data- 属性のデータは JSON に自動でシリアライズまでしてくれます。

{* null は属性を取り除きます *}
<div title={$title}>

{* 真偽値が真偽値属性の有無を制御します *}
<input type="checkbox" checked={$isChecked}>

{* class では配列が使えます *}
<div class={['btn', 'btn-primary', active => $isActive]}>

{* data- 属性では配列が JSON にエンコードされます *}
<div data-config={[theme: dark, version: 2]}>

詳しくは別の章スマートな HTML 属性をご覧ください。

フィルタ

標準フィルタの一覧をご覧ください。

フィルタはパイプ記号のあとに書きます(前に空白があってもかまいません)。

<h1>{$heading|upper}</h1>

フィルタは連ねられ、左から右の順に適用されます。

<h1>{$heading|lower|capitalize}</h1>

引数はフィルタ名のあとにコロンで続け、さらに引数があればカンマで区切ります。かっこを使った呼び出しもできます。

<h1>{$heading|truncate:20,''}</h1>
<h1>{$heading|truncate(20, '')}</h1>

フィルタは式に対しても適用できます。

{var $name = ($title|upper) . ($subtitle|lower)}

ブロックに対しても。

<h1>{block |lower}{$heading}{/block}</h1>

値に直接適用することもできます({=expr} タグとの組み合わせ)。

<h1>{='  Hello world  '|trim}</h1>

値が null になり得て、その場合はフィルタを適用したくないなら、nullsafe フィルタ ?| を使います。

<h1>{$heading?|upper}</h1>

動的 HTML タグ

Latte は動的な HTML タグに対応しています。タグ名に柔軟さが必要なときに便利です。

<h{$level}>見出し</h{$level}>

たとえば上のコードは、変数 $level の値に応じて <h1>見出し</h1> や <h2>見出し</h2> を生成できます。Latte の動的 HTML タグは常にペアでなければなりません。代わりの手段は n:tag です。

Latte は安全なテンプレートシステムなので、できあがるタグ名が正しいこと、望ましくない値や悪意ある値を含まないことを確認します。また、終了タグの名前が常に開始タグの名前と一致するようにします。

コメント

コメントは次のように書き、出力には現れません。

{* これは Latte のコメントです *}

タグの中では PHP のコメントが使えます。

{include 'file.info', /* value: 123 */}

空白の制御

Latte は空白を賢く扱います。読みやすさのために自由にインデントしても、出力はきれいなままです。制御タグが行にひとつだけある場合、その行全体(インデントと改行)が出力から取り除かれます({$var}、{=...}、{_...} のように出力を行うタグには当てはまらず、そのインデントと末尾の改行は保たれます)。

<ul>
	{foreach $items as $item}
	<li>{$item}</li>
	{/foreach}
</ul>

出力:

<ul>
	<li>foo</li>
	<li>bar</li>
</ul>

タグが行にひとつだけではなく、ほかの内容と並んでいる場合はどうでしょうか。タグの前の空白は、タグの内側に属します。

<div>
	{if $foo}hello{/if}
</div>

インデントは実質的に {if} の内側にあります。$foo が偽なら何も出力されず、インデントも空行も残りません。$foo が真なら、出力には自然にインデントが含まれます。整った構造のテンプレートを書くだけで、出力は常にきれいになります。

さらにきれいな出力がほしいときは、Dedent機能を有効にできます。これは {if} や {foreach} のようなペアタグの入れ子によって生じるインデントも取り除きます。

シンタックスシュガー

引用符のない文字列

単純な文字列では引用符を省けます。

PHP と同じ: {var $arr = ['hello', 'btn--default', '€']}

短縮形:     {var $arr = [hello, btn--default, €]}

単純な文字列とは、英字、数字、アンダースコア、ハイフン、ピリオドだけで構成されたものです。数字で始まってはならず、ハイフンで始まったり終わったりしてもいけません。大文字とアンダースコアだけで構成されていると定数(PHP_VERSION など)とみなされるので、それも避けます。また、次のキーワードと衝突してはいけません: and、array、clone、default、false、in、instanceof、new、null、or、return、true、xor。

定数

グローバル定数と単純な文字列を区別するには、グローバル名前空間の区切りを使います。

{if \PROJECT_ID === 1} ... {/if}

この書き方は PHP 自体でもまったく正しく、バックスラッシュはその定数がグローバル名前空間にあることを示します。

短縮三項演算子

三項演算子の 3 つめの値が空なら、省略できます。

PHP と同じ: {$stock ? '在庫あり' : ''}

短縮形:     {$stock ? '在庫あり'}

配列のキーの現代的な書き方

配列のキーは、関数呼び出しの名前付き引数と同じように書けます。

PHP と同じ: {var $arr = ['one' => 'item 1', 'two' => 'item 2']}

現代的:     {var $arr = [one: 'item 1', two: 'item 2']}

フィルタ

フィルタは任意の式に使えます。式全体をかっこで囲むだけです。

{var $content = ($text|truncate: 30|upper)}

in 演算子

in 演算子は in_array() 関数の代わりになります。比較は常に厳密です。

{* in_array($item, $items, true) と同じ *}
{if $item in $items}
	...
{/if}

歴史をのぞく窓

Latte はその歴史の中で、数年後に PHP 自体に登場することになるシンタックスシュガーをいくつも先取りしてきました。たとえば Latte では、PHP で可能になるずっと前から array(1, 2, 3) の代わりに [1, 2, 3] と書けましたし、nullsafe 演算子 $obj?->foo も使えました。今の PHP の ...$arr 演算子にあたる配列展開演算子 (expand) $arr も、Latte が先に導入したものです。

Latte における PHP の制限

Latte には PHP の式しか書けません。つまりセミコロンで終わる文は使えません。クラスの宣言もできませんし、if、foreach、switch、return、try、throw などの制御構造も使えません。それらには Latte がタグを用意しています。属性、バッククォート、一部のマジック定数も使えません。unset、echo、include、require、exit、eval も使えません。これらは関数ではなく PHP の特別な言語構造であり、式ではないからです。コメントは複数行の /* ... */ だけがサポートされます。

とはいえ、RawPhpExtension 拡張を有効にすればこの制限を回避でき、テンプレート作者の責任のもとで {php ...} タグの中に任意の PHP コードを書けます。