Nette Documentation Preview

syntax
Latte タグ
********

.[perex]
Latte テンプレートシステムで既定で使えるすべてのタグの概要と説明です。

.[table-latte-tags language-latte]
|## 出力
| `{$var}`、`{...}`、`{=...}`     | [エスケープした変数や式を出力する |#出力]
| `{$var\|filter}`               | [フィルタを適用して出力する |#フィルタ]
| `{l}`、`{r}`                    | `{` または `}` の文字を出力する

.[table-latte-tags language-latte]
|## 条件
| `{if}` … `{elseif}` … `{else}` … `{/if}`    | [if 条件 |#{if} {elseif} {else}]
| `{ifset}` … `{elseifset}` … `{/ifset}`      | [ifset 条件 |#{ifset} {elseifset}]
| `{ifchanged}` … `{/ifchanged}`              | [値が変わったかを調べる |#{ifchanged}]
| `{switch}` `{case}` `{default}` `{/switch}` | [switch 条件 |#{switch} {case} {default}]
| `n:else`、`n:elseif`                        | [条件の代替となる内容 |#n:else]

.[table-latte-tags language-latte]
|## ループ
| `{foreach}` … `{/foreach}`     | [#{foreach}]
| `{for}` … `{/for}`             | [#{for}]
| `{while}` … `{/while}`         | [#{while}]
| `{continueIf $cond}`           | [次の反復に進む |#{continueIf} {skipIf} {breakIf}]
| `{skipIf $cond}`               | [現在の反復を飛ばす |#{continueIf} {skipIf} {breakIf}]
| `{breakIf $cond}`              | [ループを抜ける |#{continueIf} {skipIf} {breakIf}]
| `{exitIf $cond}`               | [早期終了 |#{exitIf}]
| `{first}` … `{/first}`         | [最初の反復か? |#{first} {last} {sep}]
| `{last}` … `{/last}`           | [最後の反復か? |#{first} {last} {sep}]
| `{sep}` … `{/sep}`             | [次の反復が続くか? |#{first} {last} {sep}]
| `{iterateWhile}` … `{/iterateWhile}` | [構造化された foreach |#{iterateWhile}]
| `$iterator`                    | [foreach ループの中の特別な変数 |#$iterator]

.[table-latte-tags language-latte]
|## ほかのテンプレートの挿入
| `{include 'file.latte'}`       | [別のファイルのテンプレートを挿入する |#include]
| `{sandbox 'file.latte'}`       | [サンドボックスモードでテンプレートを挿入する |#{sandbox}]

.[table-latte-tags language-latte]
|## ブロック、レイアウト、テンプレート継承
| `{block}`                      | [無名ブロック |#{block}]
| `{block blockname}`            | [ブロックを定義する |template-inheritance#Blocks]
| `{define blockname}`           | [あとで使うブロックを定義する |template-inheritance#Definitions]
| `{include blockname}`          | [ブロックをレンダリングする |template-inheritance#Printing Blocks]
| `{include blockname from 'file.latte'}` | [ファイルのブロックをレンダリングする |template-inheritance#Printing Blocks]
| `{import 'file.latte'}`        | [テンプレートからブロックを取り込む |template-inheritance#Horizontal Reuse]
| `{layout 'file.latte'}` / `{extends}` | [レイアウトファイルを指定する |template-inheritance#Layout Inheritance]
| `{embed}` … `{/embed}`         | [テンプレートやブロックを埋め込み、ブロックの上書きを許す |template-inheritance#Unit Inheritance]
| `{ifset blockname}` … `{/ifset}`   | [ブロックの存在を調べる条件 |template-inheritance#Checking Block Existence]

.[table-latte-tags language-latte]
|## 例外処理
| `{try}` … `{else}` … `{/try}`  | [例外を捕まえる |#{try}]
| `{rollback}`                   | [try ブロックを破棄する |#{rollback}]

.[table-latte-tags language-latte]
|## 変数
| `{var $foo = value}`           | [変数を作る |#var-default]
| `{default $foo = value}`       | [変数がなければ作る |#var-default]
| `{parameters}`                 | [変数・型・既定値を宣言する |#{parameters}]
| `{capture}` … `{/capture}`     | [出力を変数に取り込む |#{capture}]

.[table-latte-tags language-latte]
|## 型
| `{varType}`                    | [変数の型を宣言する |type-system#{varType}]
| `{varPrint}`                   | [変数の型の案を出す |type-system#{varPrint}]
| `{templateType}`               | [クラスにもとづいて変数の型を宣言する |type-system#{templateType}]
| `{templatePrint}`              | [変数の型を持つクラスの案を出す |type-system#{templatePrint}]

.[table-latte-tags language-latte]
|## 翻訳
| `{_...}`                       | [翻訳を出力する |#翻訳]
| `{translate}` … `{/translate}` | [内容を翻訳する |#翻訳]

.[table-latte-tags language-latte]
|## そのほか
| `{contentType}`                | [エスケープを切り替え、HTTP ヘッダーを送る |#{contentType}]
| `{debugbreak}`                 | [コードにブレークポイントを置く |#{debugbreak}]
| `{do}`                         | [何も出力せずにコードを実行する |#{do}]
| `{dump}`                       | [変数を Tracy バーにダンプする |#{dump}]
| `{php}`                        | [任意の PHP コードを実行する |#{php}]
| `{spaceless}` … `{/spaceless}` | [不要な空白を取り除く |#{spaceless}]
| `{syntax}`                     | [実行時に構文を変える |#{syntax}]
| `{trace}`                      | [スタックトレースを表示する |#{trace}]

.[table-latte-tags language-latte]
|## HTML コーダー向けの補助
| `n:class`                      | [動的な HTML の class 属性 |#n:class]
| `n:attr`                       | [動的な HTML 属性 |#n:attr]
| `n:tag`                        | [動的な HTML 要素名 |#n:tag]
| `n:ifcontent`                  | [空の HTML タグを省く |#n:ifcontent]

.[table-latte-tags language-latte]
|## Nette Framework でのみ使えるもの
| `n:href`                       | [`<a>` HTML 要素で使うリンク |application:creating-links#プレゼンターのテンプレートで]
| `{link}`                       | [リンクを出力する |application:creating-links#プレゼンターのテンプレートで]
| `{plink}`                      | [プレゼンターへのリンクを出力する |application:creating-links#プレゼンターのテンプレートで]
| `{linkBase}`                   | [リンクの基準を変える |application:creating-links#リンクの基準の変更]
| `{control}`                    | [コンポーネントをレンダリングする |application:components#描画]
| `{snippet}` … `{/snippet}`     | [AJAX で送れるテンプレートのスニペット |application:ajax#Latte でのスニペット]
| `{snippetArea}`                | [スニペットの包み |application:ajax#スニペット領域]
| `{cache}` … `{/cache}`         | [テンプレートの一部をキャッシュする |caching:#Latte でのキャッシュ]

.[table-latte-tags language-latte]
|## Nette Forms でのみ使えるもの
| `{form}` … `{/form}`           | [フォームのタグをレンダリングする |forms:rendering#{form}]
| `{form scope}`、`{form detached}` | [タグなし、または切り離されたフォームの変種 |forms:rendering#{form}]
| `{label}` … `{/label}`         | [フォーム要素のラベルをレンダリングする |forms:rendering#{label} {input}]
| `{input}`                      | [フォーム要素をレンダリングする |forms:rendering#{label} {input}]
| `{inputError}`                 | [フォーム要素のエラーメッセージを出力する |forms:rendering#{inputError}]
| `n:name`                       | [フォーム要素を有効にする |forms:rendering#n:name]
| `{formContainer}` … `{/formContainer}` | [フォームのコンテナをレンダリングする |forms:rendering#特別な場合]

.[table-latte-tags language-latte]
|## Nette Assets でのみ使えるもの
| `{asset}`                      | [アセットを HTML 要素または URL としてレンダリングする |assets:#{asset}]
| `{preload}`                    | [性能最適化のためのプリロードヒントを生成する |assets:#{preload}]
| `n:asset`                      | [HTML 要素にアセットの属性を追加する |assets:#n:asset]


出力
===


`{$var}` `{...}` `{=...}`
-------------------------

Latte では、任意の式を出力に書き出すために `{=...}` タグを使います。Latte はあなたの快適さを大切にするので、式が変数や関数呼び出しで始まる場合は等号を書く必要がありません。実際のところ、ほとんど書く必要はないということです。

```latte
Name: {$name} {$surname}<br>
Age: {date('Y') - $birth}<br>
```

式には PHP で知っていることを何でも書けます。新しい言語を覚える必要はありません。たとえば次のようにです。


```latte
{='0' . ($num ?? $num * 3) . ', ' . \PHP_VERSION}
```

先ほどの例に意味を探さないでください。もし見つけたら教えてくださいね :-)


出力のエスケープ
--------

テンプレートシステムの最も大切な仕事は何でしょうか。セキュリティ脆弱性を防ぐことです。そして Latte は、何かを出力するたびにまさにそれを行います。自動的にエスケープするのです。

```latte
<p>{='one < two'}</p>   {* 出力: '<p>one &lt; two</p>' *}
```

正確にいえば Latte はコンテキストに応じたエスケープを使います。これはとても重要で他にない機能なので、[専用の章 |safety-first#コンテキストに応じたエスケープ]を設けています。

信頼できる出所の HTML 化された内容を出力する場合はどうでしょうか。そのときはエスケープを簡単に無効にできます。

```latte
{$trustedHtmlString|noescape}
```

.[warning]
`noescape` フィルタの誤用は XSS 脆弱性につながります。何をしているのか、そして出力する文字列が信頼できる出所のものであることに**絶対の確信**がない限り、決して使わないでください。


JavaScript での出力
---------------

コンテキストに応じたエスケープのおかげで、JavaScript の中に変数を出力するのは驚くほど簡単で、適切なエスケープは Latte が引き受けてくれます。

変数は文字列である必要はなく、どんなデータ型でも扱え、その場合は JSON にエンコードされます。

```latte
{var $foo = ['hello', true, 1]}
<script>
	alert({$foo});
</script>
```

次を生成します。

```latte
<script>
	alert(["hello", true, 1]);
</script>
```

だからこそ、変数の周りに**引用符を書いてはいけません**。文字列には Latte が自動的に付けます。文字列の変数を別の文字列に差し込みたいなら、単に連結してください。

```latte
<script>
	alert('Hello ' + {$name} + '!');  // OK

	alert({="Hello $name!"});         // OK

	alert('Hello {$name} !');         // エラー!
</script>
```


フィルタ
----

出力する式は[フィルタ |syntax#フィルタ]で加工できます。たとえば次の例は文字列を大文字にし、最大 30 文字に短くします。

```latte
{$string|upper|truncate:30}
```

式の一部にフィルタを適用することもできます。

```latte
{$left . ($middle|upper) . $right}
```


条件
===


`{if}` `{elseif}` `{else}`
--------------------------

条件は PHP のものとまったく同じように振る舞います。PHP で知っている式をそのまま使えるので、新しい言語を覚える必要はありません。

```latte
{if $product->inStock > Stock::Minimum}
	在庫あり
{elseif $product->isOnWay()}
	入荷予定
{else}
	在庫なし
{/if}
```

ほかのペアタグと同じく、`{if} ... {/if}` のペアも [n:属性 |syntax#n:属性]で書けます。たとえば次のようにです。

```latte
<p n:if="$count > 0">在庫あり {$count} 点</p>
```

n:属性に `tag-` 接頭辞を付けられることをご存じですか。すると条件は HTML タグの出力にだけ影響し、そのあいだの内容は常に出力されます。

```latte
<a href="..." n:tag-if="$clickable">Hello</a>

{* $clickable が偽なら 'Hello' を出力 *}
{* $clickable が真なら '<a href="...">Hello</a>' を出力 *}
```

素晴らしいですね。


`n:else` `n:elseif` .{toc: n:else}{data-version:3.0.12}
-------------------------------------------------------

`{if} ... {/if}` の条件を [n:属性 |syntax#n:属性]の形で書く場合、`n:else`(3.0.12 以降)と `n:elseif`(3.1 以降)で代替の分岐を指定できます。

```latte
<strong n:if="$count > 0">在庫あり {$count} 点</strong>

<em n:elseif="$count < 0">個数が不正です</em>

<em n:else>在庫なし</em>
```

`n:else` 属性は [`n:ifset` |#{ifset} {elseifset}]、[`n:foreach` |#{foreach}]、[`n:try` |#{try}]、[`n:ifcontent`|#n:ifcontent]、[`n:ifchanged` |#{ifchanged}]と組み合わせても使えます。


`{/if $cond}`
-------------

`{if}` 条件の式は終了タグに書くこともできる、と聞いたら驚くかもしれません。これは、条件を開くときにまだ値が分からない場面で役立ちます。遅延した判断とでも呼びましょう。

たとえば、データベースのレコードを表として出力し始めたものの、出力を終えてはじめてデータベースにレコードがなかったと気づく場合です。そこで条件を終了タグ `{/if}` に置けば、レコードがないときには何も出力されません。

```latte
{if}
	<h1>データベースのレコード一覧</h1>

	<table>
	{foreach $resultSet as $row}
		...
	{/foreach}
	</table>
{/if isset($row)}
```

便利でしょう。

遅延した条件では `{else}` も使えますが、`{elseif}` は使えません。


`{ifset}` `{elseifset}`
-----------------------

.[note]
[`{ifset block}` |template-inheritance#Checking Block Existence]も参照してください

変数(または複数の変数)が存在し、値が null でないかを判定するには `{ifset $var}` 条件を使います。実質的には PHP の `if (isset($var))` と同じです。ほかのペアタグと同じく [n:属性 |syntax#n:属性]でも書けるので、その例を示しましょう。

```latte
<meta name="robots" content={$robots} n:ifset="$robots">
```


`{ifchanged}`
-------------

`{ifchanged}` は、ループ(foreach、for、while)の前回の反復から変数の値が変わったかを調べます。

タグに 1 つ以上の変数を渡すと、そのいずれかが変わったかを調べ、それに応じて内容を出力します。たとえば次の例は、名前を並べる途中で頭文字が変わるたびに、それを見出しとして出力します。

```latte
{foreach ($names|sort) as $name}
	{ifchanged $name[0]} <h2>{$name[0]}</h2> {/ifchanged}

	<p>{$name}</p>
{/foreach}
```

引数を渡さない場合は、レンダリングされた内容そのものが前回の状態と比べられます。つまり先ほどの例では、タグの引数を安心して省けます。もちろん [n:属性 |syntax#n:属性]も使えます。

```latte
{foreach ($names|sort) as $name}
	<h2 n:ifchanged>{$name[0]}</h2>

	<p>{$name}</p>
{/foreach}
```

`{ifchanged}` の中では `{else}` 節も使えます。


`{switch}` `{case}` `{default}`
-------------------------------
値を複数の選択肢と比べます。PHP で知られる `switch` 文に似ていますが、Latte はそれを改良しています。

- 厳密な比較(`===`)を使う
- `break` が要らない

つまり PHP 8.0 で導入された `match` 構造にとてもよく似ています。

```latte
{switch $transport}
	{case train}
		電車で
	{case plane}
		飛行機で
	{default}
		それ以外
{/switch}
```

`{case}` 節にはカンマで区切って複数の値を書けます。

```latte
{switch $status}
{case $status::New}<b>新商品</b>
{case $status::Sold, $status::Unknown}<i>在庫なし</i>
{/switch}
```


ループ
===

Latte には PHP で知っているループがすべて揃っています。foreach、for、while です。


`{foreach}`
-----------

ループは PHP とまったく同じように書きます。

```latte
{foreach $langs as $code => $lang}
	<span>{$lang}</span>
{/foreach}
```

さらに、これから説明するいくつかの便利な機能があります。

たとえば Latte は、作られた変数が同じ名前のグローバル変数をうっかり上書きしていないかを確認します。`$lang` にページの現在の言語が入っているつもりでいたのに、`foreach $langs as $lang` がその変数を上書きしていた、といった事態から救ってくれます。

foreach ループは [n:属性 |syntax#n:属性]を使って、とてもきれいに簡潔に書けます。

```latte
<ul>
	<li n:foreach="$items as $item">{$item->name}</li>
</ul>
```

n:属性に `inner-` 接頭辞を付けられることをご存じですか。すると要素の内側の部分だけがループで繰り返されます。

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

つまり次のように出力されます。

```latte
<div>
	<h4>Foo</h4>
	<p>Lorem ipsum.</p>
	<h4>Bar</h4>
	<p>Sit dolor.</p>
</div>
```


`{else}` .{toc: foreach-else}
-----------------------------

`foreach` ループの中には `{else}` 節を書けます。その内容は、ループが空のときに表示されます。

```latte
<ul>
	{foreach $people as $person}
		<li>{$person->name}</li>
	{else}
		<li><em>申し訳ありません、このリストにユーザーはいません</em></li>
	{/foreach}
</ul>
```


`$iterator`
-----------

`foreach` ループの中で、Latte は `$iterator` 変数を作ります。これで進行中のループについて役立つ情報を得られます。

- `$iterator->first` - これは最初の反復か?
- `$iterator->last` - これは最後の反復か?
- `$iterator->counter` - 反復のカウンタ。1 から始まります
- `$iterator->counter0` - 反復のカウンタ。0 から始まります
- `$iterator->odd` - これは奇数回目の反復か?
- `$iterator->even` - これは偶数回目の反復か?
- `$iterator->parent` - 現在のイテレータを囲むイテレータ
- `$iterator->nextValue` - ループの次の項目
- `$iterator->nextKey` - ループの次の項目のキー


```latte
{foreach $rows as $row}
	{if $iterator->first}<table>{/if}

	<tr id="row-{$iterator->counter}">
		<td>{$row->name}</td>
		<td>{$row->email}</td>
	</tr>

	{if $iterator->last}</table>{/if}
{/foreach}
```

Latte は賢いので、`$iterator->last` は配列だけでなく、あらかじめ項目数が分からない一般的なイテレータ上のループでも働きます。


`{first}` `{last}` `{sep}`
--------------------------

これらのタグは `{foreach}` ループの中で使えます。`{first}` の内容は最初の反復のときにレンダリングされます。`{last}` の内容は……お分かりですね。そう、最後の反復のときです。実際にはこれらは `{if $iterator->first}` と `{if $iterator->last}` の近道です。

これらのタグは [n:属性 |syntax#n:属性]としてもきれいに使えます。

```latte
{foreach $rows as $row}
	{first}<h1>名前の一覧</h1>{/first}

	<p>{$row->name}</p>

	<hr n:last>
{/foreach}
```

`{sep}` タグの内容は、その反復が最後でないときにレンダリングされるので、並べた項目のあいだのカンマのような区切りを出すのに向いています。

```latte
{foreach $items as $item} {$item} {sep}, {/sep} {/foreach}
```

なかなか実用的でしょう。


`{iterateWhile}`
----------------

条件が満たされているあいだ入れ子のループで反復することで、foreach ループでの繰り返し中に線形のデータをグループ化するのを簡単にします。[詳しい説明をご覧ください|cookbook/grouping]。

先ほどの例の `{first}` と `{last}` を、きれいに置き換えることもできます。

```latte
{foreach $rows as $row}
	<table>

	{iterateWhile}
	<tr id="row-{$iterator->counter}">
		<td>{$row->name}</td>
		<td>{$row->email}</td>
	</tr>
	{/iterateWhile true}

	</table>
{/foreach}
```

[batch |filters#batch]と [group |filters#group]のフィルタも参照してください。


`{for}`
-------

ループは PHP とまったく同じように書きます。

```latte
{for $i = 0; $i < 10; $i++}
	<span>項目 #{$i}</span>
{/for}
```

このタグは [n:属性 |syntax#n:属性]としても書けます。

```latte
<h1 n:for="$i = 0; $i < 10; $i++">{$i}</h1>
```


`{while}`
---------

これも PHP とまったく同じように書きます。

```latte
{while $row = $result->fetch()}
	<span>{$row->title}</span>
{/while}
```

あるいは [n:属性 |syntax#n:属性]として。

```latte
<span n:while="$row = $result->fetch()">
	{$row->title}
</span>
```

条件を終了タグに書く形も可能で、PHP の do-while ループに対応します。

```latte
{while}
	<span>{$item->title}</span>
{/while $item = $item->getNext()}
```


`{continueIf}` `{skipIf}` `{breakIf}`
-------------------------------------

特別なタグ `{continueIf ?}` と `{breakIf ?}` は、どんなループの制御にも使えます。条件が満たされると、それぞれ次の反復へ飛ぶか、ループを終えます。

```latte
{foreach $rows as $row}
	{continueIf $row->date < $now}
	{breakIf $row->parent === null}
	...
{/foreach}
```


`{skipIf}` タグは `{continueIf}` とよく似ていますが、`$iterator->counter` を増やしません。これにより、カウンタを出力しつつ一部の項目を飛ばすときに番号が飛ぶのを防げます。また、すべての項目が飛ばされた場合には `{else}` 節がレンダリングされます。

```latte
<ul>
	{foreach $people as $person}
		{skipIf $person->age < 18}
		<li>{$iterator->counter}. {$person->name}</li>
	{else}
		<li><em>申し訳ありません、このリストに成人はいません</em></li>
	{/foreach}
</ul>
```


`{exitIf}` .{data-version:3.0.5}
--------------------------------

条件が満たされたとき、テンプレートやブロックのレンダリングを終えます(つまり「早期終了」です)。

```latte
{exitIf !$messages}

<h1>メッセージ</h1>
<div n:foreach="$messages as $message">
   {$message}
</div>
```


テンプレートの挿入
=========


`{include 'file.latte'}` .{toc: include}
----------------------------------------

.[note]
[`{include block}` |template-inheritance#Printing Blocks]と [`{embed}` |template-inheritance#Unit Inheritance]も参照してください

`{include}` タグは指定したテンプレートを読み込んでレンダリングします。私たちの大好きな PHP でいえば、次のようなものです。

```php
<?php include 'header.phtml'; ?>
```

挿入されたテンプレートは現在のコンテキストの変数にはアクセスできませんが、グローバル変数にはアクセスできます。

挿入するテンプレートには次のようにして変数を渡せます。

```latte
{include 'template.latte', foo: 'bar', id: 123}
```

テンプレート名には任意の PHP の式を使えます。

```latte
{include $someVar}
{include $ajax ? 'ajax.latte' : 'not-ajax.latte'}
```

テンプレートが存在するかは [`hasTemplate()` |functions#hasTemplate()] 関数で調べられます。

挿入される内容は[フィルタ |syntax#フィルタ]で加工できます。次の例はすべての HTML を取り除き、大文字小文字を整えます。

```latte
<title>{include 'heading.latte' |stripHtml|capitalize}</title>
```

既定では、ここに[テンプレート継承|template-inheritance]は関わりません。挿入されるテンプレートの中でブロックを使うことはできますが、それが挿入先のテンプレートの対応するブロックを置き換えることはありません。挿入されるテンプレートは、ページやモジュールの独立した遮蔽された部分だと考えてください。この振る舞いは `with blocks` 修飾子で変えられます。

```latte
{include 'template.latte' with blocks}
```

タグに書いたファイル名とディスク上のファイルとの関係は[ローダー|loaders]に依存します。


`{sandbox}`
-----------

エンドユーザーが作ったテンプレートを挿入する場合は、サンドボックス化を検討すべきです(詳しくは[サンドボックスのドキュメント|sandbox]をご覧ください)。

```latte
{sandbox 'untrusted.latte', level: 3, data: $menu}
```


`{block}`
=========

.[note]
[`{block name}` |template-inheritance#Blocks]も参照してください

名前のないブロックは、テンプレートの一部に[フィルタ |syntax#フィルタ]を適用する手段になります。たとえば不要な空白を取り除く [spaceless |filters#spaceless] フィルタを適用できます。

```latte
{block|spaceless}
<ul>
	<li>Hello World</li>
</ul>
{/block}
```


例外処理
====


`{try}`
-------

このタグのおかげで、堅牢なテンプレートを作るのがきわめて簡単になります。

`{try}` ブロックのレンダリング中に例外が起きると、ブロック全体が破棄され、レンダリングはそのあとから続きます。

```latte
{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
{/try}
```

省略可能な `{else}` 節の内容は、例外が起きたときにだけレンダリングされます。

```latte
{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
	{else}
	<p>申し訳ありません、ツイートを読み込めませんでした。</p>
{/try}
```

このタグは [n:属性 |syntax#n:属性]としても書けます。

```latte
<ul n:try>
	...
</ul>
```

たとえばログ記録のために、独自の[例外ハンドラ |develop#例外ハンドラ]を定義することもできます。


`{rollback}`
------------

`{try}` ブロックは `{rollback}` を使って手動で止めて飛ばすこともできます。こうすれば、すべての入力データをあらかじめ確認する必要はなく、レンダリング中になってから、その対象をまったく描かないと決められます。

```latte
{try}
<ul>
	{foreach $people as $person}
 		{skipIf $person->age < 18}
 		<li>{$person->name}</li>
	{else}
		{rollback}
	{/foreach}
</ul>
{/try}
```


変数
===


`{var}` `{default}` .{toc: var-default}
---------------------------------------

テンプレートで新しい変数を作るには `{var}` タグを使います。

```latte
{var $name = 'John Smith'}
{var $age = 27}

{* 複数の宣言 *}
{var $name = 'John Smith', $age = 27}
```

`{default}` タグも同じように働きますが、変数が存在しない場合にだけ作ります。変数がすでに存在していて値が `null` の場合、上書きはされません。

```latte
{default $lang = 'en'}
```

[変数の型|type-system]も指定できます。今のところ情報提供のためのもので、Latte はチェックしません。

```latte
{var string $name = $article->getTitle()}
{default int $id = 0}
```


`{parameters}`
--------------

関数が引数を宣言するのと同じように、テンプレートも先頭で変数を宣言できます。

```latte
{parameters
	$a,
	?int $b,
	int|string $c = 10
}
```

既定値を指定しない変数 `$a` と `$b` は、自動的に既定値 `null` を持ちます。宣言された型は現時点では情報提供のためのもので、Latte はチェックしません。

宣言されたもの以外の変数はテンプレートに渡されません。この点が `{default}` タグとは異なります。


`{capture}`
-----------

出力を変数に取り込みます。

```latte
{capture $var}
<ul>
	<li>Hello World</li>
</ul>
{/capture}

<p>Captured: {$var}</p>
```

ほかのペアタグと同じく、このタグも [n:属性 |syntax#n:属性]として書けます。

```latte
<ul n:capture="$var">
	<li>Hello World</li>
</ul>
```

HTML の出力は、出力時に[望まないエスケープを防ぐ |develop#変数の自動エスケープの無効化]ため、`Latte\Runtime\Html` オブジェクトとして `$var` 変数に格納されます。


そのほか
====


`{contentType}`
---------------

このタグで、テンプレートが表す内容の種類を指定します。選べるのは次のとおりです。

- `html`(既定の種類)
- `xml`
- `javascript`
- `css`
- `calendar`(iCal)
- `text`

これを使うことが重要なのは、[コンテキストに応じたエスケープ |safety-first#コンテキストに応じたエスケープ]を設定するからで、そうしてはじめて Latte は正しくエスケープできます。たとえば `{contentType xml}` は XML モードに切り替え、`{contentType text}` はエスケープを完全に無効にします。

パラメータが `application/xml` のような完全な MIME タイプなら、`Content-Type` の HTTP ヘッダーもブラウザに送ります。

```latte
{contentType application/xml}
<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>RSS feed</title>
		<item>
			...
		</item>
	</channel>
</rss>
```


`{debugbreak}`
--------------

プログラムの実行を止める地点を指定します。デバッグの目的で使い、プログラマーが実行時の環境を調べ、コードが期待どおりに動いているか確かめられます。[Xdebug |https://xdebug.org/]に対応しています。いつプログラムを止めるかを決める条件も付けられます。

```latte
{debugbreak}                {* プログラムを止める *}

{debugbreak $counter == 1}  {* 条件が満たされたらプログラムを止める *}
```


`{do}`
------

PHP のコードを実行し、何も出力しません。ほかのすべてのタグと同じく、PHP のコードとはひとつの式のことです。[PHP の制限 |syntax#Latte における PHP の制限]をご覧ください。

```latte
{do $num++}
```


`{dump}`
--------

変数や現在のコンテキストをダンプします。

```latte
{dump $name} {* $name 変数をダンプする *}

{dump}       {* 現在定義されているすべての変数をダンプする *}
```

.[caution]
[Tracy|tracy:]ライブラリが必要です。


`{php}`
-------

既定では `{php}` は [`{do}` |#{do}]の古い別名として働き、ひとつの式だけを評価します。任意の PHP コードを実行するには、[RawPhpExtension |develop#RawPhpExtension]拡張でこのタグを有効にする必要があります。


`{spaceless}`
-------------

出力から不要な空白を取り除きます。[spaceless |filters#spaceless] フィルタと同じように働きます。

```latte
{spaceless}
	<ul>
		<li>Hello</li>
	</ul>
{/spaceless}
```

次を生成します。

```latte
<ul> <li>Hello</li> </ul>
```

このタグは [n:属性 |syntax#n:属性]としても書けます。


`{syntax}`
----------

Latte のタグは単一の波かっこで囲まなければならないわけではありません。実行時であっても、別の区切りを選べます。それを行うのが `{syntax …}` で、パラメータには次のものを指定できます。

- double: `{{...}}`
- off: Latte のタグ処理を完全に無効にする

n:属性を使えば、たとえば JavaScript のひとつのブロックについてだけ Latte を無効にできます。

```latte
<script n:syntax="off">
	var obj = {var: 123}; // これはもうタグではありません
</script>
```

Latte は JavaScript の中でもとても快適に使えます。この例のように `{` の直後に文字が続く書き方だけ避けてください。[JavaScript や CSS の中の Latte |recipes#JavaScript や CSS の中の Latte]をご覧ください。

`{syntax off}`(n:属性ではなくタグのほう)で Latte を無効にすると、`{/syntax}` までのすべてのタグを厳密に無視します。


`{trace}`
---------

`Latte\RuntimeException` 例外を投げます。そのスタックトレースはテンプレートの流儀に沿ったものです。つまり関数やメソッドの呼び出しではなく、ブロックの呼び出しやテンプレートの挿入が並びます。[Tracy|tracy:]のように投げられた例外を見やすく表示するツールを使っていれば、渡されたすべての引数を含む呼び出しスタックがはっきり分かります。


HTML コーダー向けの補助
==============


`n:class`
---------

.[note]
Latte 3.1 以降、標準の HTML の class 属性が[同じ機能 |html-attributes#クラス]を備えました。ですから n:class を使う必要はもうありません。

`n:class` のおかげで、HTML の `class` 属性を望みどおりに生成するのがとても簡単になります。

例: アクティブな要素に `active` クラスを付けたいとします。

```latte
{foreach $items as $item}
	<a n:class="$item->isActive() ? active">...</a>
{/foreach}
```

さらに、最初の要素には `first` と `main` のクラスを付けたいとします。

```latte
{foreach $items as $item}
	<a n:class="$item->isActive() ? active, $iterator->first ? 'first main'">...</a>
{/foreach}
```

そしてすべての要素に `list-item` クラスを付けたいとします。

```latte
{foreach $items as $item}
	<a n:class="$item->isActive() ? active, $iterator->first ? 'first main', list-item">...</a>
{/foreach}
```

驚くほど簡単でしょう。


`n:attr`
--------

`n:attr` 属性は、[#n:class]と同じ優雅さで任意の HTML 属性を生成できます。

```latte
{foreach $data as $item}
	<input type="checkbox" n:attr="value: $item->getValue(), checked: $item->isActive()">
{/foreach}
```

返される値に応じて、たとえば次のように出力します。

```latte
<input type="checkbox">

<input type="checkbox" value="Hello">

<input type="checkbox" value="Hello" checked>
```

`null` の値を落とす、`class` や `style` に配列を渡すといった Latte 3.1 のスマート属性の機能は、`n:attr` の中でも働きます。

```latte
<div n:attr="class: [a, b], title: $title"></div>
```


`n:tag`
-------

`n:tag` 属性は HTML 要素の名前を動的に変えられます。

```latte
<h1 n:tag="$heading" class="main">{$title}</h1>
```

`$heading === null` なら `<h1>` タグはそのまま出力されます。そうでなければ要素名が変数の値に変わるので、`$heading === 'h3'` なら次のように書き出されます。

```latte
<h3 class="main">...</h3>
```

Latte は安全なテンプレートシステムなので、新しいタグ名が正しいこと、望ましくない値や悪意ある値を含まないことを確認します。


`n:ifcontent`
-------------

空の HTML 要素、つまり空白しか含まない要素が出力されるのを防ぎます。

```latte
<div>
	<div class="error" n:ifcontent>{$error}</div>
</div>
```

変数 `$error` の値に応じて、次のように出力されます。

```latte
{* $error = '' *}
<div>
</div>

{* $error = 'Required' *}
<div>
	<div class="error">Required</div>
</div>
```


翻訳
===

翻訳のタグを使えるようにするには、[トランスレーターを有効にする |develop#TranslatorExtension]必要があります。翻訳には [`translate` |filters#translate] フィルタも使えます。


`{_...}`
--------

値をほかの言語に翻訳します。

```latte
<a href="basket">{_'カート'}</a>
<span>{_$item}</span>
```

トランスレーターにはほかのパラメータも渡せます。

```latte
<a href="basket">{_'カート', domain: order}</a>
```


`{translate}`
-------------

テンプレートの一部を翻訳します。

```latte
<h1>{translate}注文{/translate}</h1>

{translate domain: order}Lorem ipsum ...{/translate}
```

このタグは [n:属性 |syntax#n:属性]としても書けて、要素の内側を翻訳します。

```latte
<h1 n:translate>注文</h1>
```

Latte タグ

Latte テンプレートシステムで既定で使えるすべてのタグの概要と説明です。

出力
{$var}{...}{=...} エスケープした変数や式を出力する
{$var|filter} フィルタを適用して出力する
{l}{r} { または } の文字を出力する
条件
{if}{elseif}{else}{/if} if 条件
{ifset}{elseifset}{/ifset} ifset 条件
{ifchanged}{/ifchanged} 値が変わったかを調べる
{switch} {case} {default} {/switch} switch 条件
n:elsen:elseif 条件の代替となる内容
ループ
{foreach}{/foreach} {foreach}
{for}{/for} {for}
{while}{/while} {while}
{continueIf $cond} 次の反復に進む
{skipIf $cond} 現在の反復を飛ばす
{breakIf $cond} ループを抜ける
{exitIf $cond} 早期終了
{first}{/first} 最初の反復か?
{last}{/last} 最後の反復か?
{sep}{/sep} 次の反復が続くか?
{iterateWhile}{/iterateWhile} 構造化された foreach
$iterator foreach ループの中の特別な変数
ほかのテンプレートの挿入
{include 'file.latte'} 別のファイルのテンプレートを挿入する
{sandbox 'file.latte'} サンドボックスモードでテンプレートを挿入する
ブロック、レイアウト、テンプレート継承
{block} 無名ブロック
{block blockname} ブロックを定義する
{define blockname} あとで使うブロックを定義する
{include blockname} ブロックをレンダリングする
{include blockname from 'file.latte'} ファイルのブロックをレンダリングする
{import 'file.latte'} テンプレートからブロックを取り込む
{layout 'file.latte'} / {extends} レイアウトファイルを指定する
{embed}{/embed} テンプレートやブロックを埋め込み、ブロックの上書きを許す
{ifset blockname}{/ifset} ブロックの存在を調べる条件
例外処理
{try}{else}{/try} 例外を捕まえる
{rollback} try ブロックを破棄する
変数
{var $foo = value} 変数を作る
{default $foo = value} 変数がなければ作る
{parameters} 変数・型・既定値を宣言する
{capture}{/capture} 出力を変数に取り込む
{varType} 変数の型を宣言する
{varPrint} 変数の型の案を出す
{templateType} クラスにもとづいて変数の型を宣言する
{templatePrint} 変数の型を持つクラスの案を出す
翻訳
{_...} 翻訳を出力する
{translate}{/translate} 内容を翻訳する
そのほか
{contentType} エスケープを切り替え、HTTP ヘッダーを送る
{debugbreak} コードにブレークポイントを置く
{do} 何も出力せずにコードを実行する
{dump} 変数を Tracy バーにダンプする
{php} 任意の PHP コードを実行する
{spaceless}{/spaceless} 不要な空白を取り除く
{syntax} 実行時に構文を変える
{trace} スタックトレースを表示する
HTML コーダー向けの補助
n:class 動的な HTML の class 属性
n:attr 動的な HTML 属性
n:tag 動的な HTML 要素名
n:ifcontent 空の HTML タグを省く
Nette Framework でのみ使えるもの
n:href <a> HTML 要素で使うリンク
{link} リンクを出力する
{plink} プレゼンターへのリンクを出力する
{linkBase} リンクの基準を変える
{control} コンポーネントをレンダリングする
{snippet}{/snippet} AJAX で送れるテンプレートのスニペット
{snippetArea} スニペットの包み
{cache}{/cache} テンプレートの一部をキャッシュする
Nette Forms でのみ使えるもの
{form}{/form} フォームのタグをレンダリングする
{form scope}{form detached} タグなし、または切り離されたフォームの変種
{label}{/label} フォーム要素のラベルをレンダリングする
{input} フォーム要素をレンダリングする
{inputError} フォーム要素のエラーメッセージを出力する
n:name フォーム要素を有効にする
{formContainer}{/formContainer} フォームのコンテナをレンダリングする
Nette Assets でのみ使えるもの
{asset} アセットを HTML 要素または URL としてレンダリングする
{preload} 性能最適化のためのプリロードヒントを生成する
n:asset HTML 要素にアセットの属性を追加する

出力

{$var} {...} {=...}

Latte では、任意の式を出力に書き出すために {=...} タグを使います。Latte はあなたの快適さを大切にするので、式が変数や関数呼び出しで始まる場合は等号を書く必要がありません。実際のところ、ほとんど書く必要はないということです。

Name: {$name} {$surname}<br>
Age: {date('Y') - $birth}<br>

式には PHP で知っていることを何でも書けます。新しい言語を覚える必要はありません。たとえば次のようにです。

{='0' . ($num ?? $num * 3) . ', ' . \PHP_VERSION}

先ほどの例に意味を探さないでください。もし見つけたら教えてくださいね :-)

出力のエスケープ

テンプレートシステムの最も大切な仕事は何でしょうか。セキュリティ脆弱性を防ぐことです。そして Latte は、何かを出力するたびにまさにそれを行います。自動的にエスケープするのです。

<p>{='one < two'}</p>   {* 出力: '<p>one &lt; two</p>' *}

正確にいえば Latte はコンテキストに応じたエスケープを使います。これはとても重要で他にない機能なので、専用の章を設けています。

信頼できる出所の HTML 化された内容を出力する場合はどうでしょうか。そのときはエスケープを簡単に無効にできます。

{$trustedHtmlString|noescape}

noescape フィルタの誤用は XSS 脆弱性につながります。何をしているのか、そして出力する文字列が信頼できる出所のものであることに絶対の確信がない限り、決して使わないでください。

JavaScript での出力

コンテキストに応じたエスケープのおかげで、JavaScript の中に変数を出力するのは驚くほど簡単で、適切なエスケープは Latte が引き受けてくれます。

変数は文字列である必要はなく、どんなデータ型でも扱え、その場合は JSON にエンコードされます。

{var $foo = ['hello', true, 1]}
<script>
	alert({$foo});
</script>

次を生成します。

<script>
	alert(["hello", true, 1]);
</script>

だからこそ、変数の周りに引用符を書いてはいけません。文字列には Latte が自動的に付けます。文字列の変数を別の文字列に差し込みたいなら、単に連結してください。

<script>
	alert('Hello ' + {$name} + '!');  // OK

	alert({="Hello $name!"});         // OK

	alert('Hello {$name} !');         // エラー!
</script>

フィルタ

出力する式はフィルタで加工できます。たとえば次の例は文字列を大文字にし、最大 30 文字に短くします。

{$string|upper|truncate:30}

式の一部にフィルタを適用することもできます。

{$left . ($middle|upper) . $right}

条件

{if} {elseif} {else}

条件は PHP のものとまったく同じように振る舞います。PHP で知っている式をそのまま使えるので、新しい言語を覚える必要はありません。

{if $product->inStock > Stock::Minimum}
	在庫あり
{elseif $product->isOnWay()}
	入荷予定
{else}
	在庫なし
{/if}

ほかのペアタグと同じく、{if} ... {/if} のペアも n:属性で書けます。たとえば次のようにです。

<p n:if="$count > 0">在庫あり {$count} 点</p>

n:属性に tag- 接頭辞を付けられることをご存じですか。すると条件は HTML タグの出力にだけ影響し、そのあいだの内容は常に出力されます。

<a href="..." n:tag-if="$clickable">Hello</a>

{* $clickable が偽なら 'Hello' を出力 *}
{* $clickable が真なら '<a href="...">Hello</a>' を出力 *}

素晴らしいですね。

n:else n:elseif

{if} ... {/if} の条件を n:属性の形で書く場合、n:else(3.0.12 以降)と n:elseif(3.1 以降)で代替の分岐を指定できます。

<strong n:if="$count > 0">在庫あり {$count} 点</strong>

<em n:elseif="$count < 0">個数が不正です</em>

<em n:else>在庫なし</em>

n:else 属性は n:ifsetn:foreachn:tryn:ifcontentn:ifchangedと組み合わせても使えます。

{/if $cond}

{if} 条件の式は終了タグに書くこともできる、と聞いたら驚くかもしれません。これは、条件を開くときにまだ値が分からない場面で役立ちます。遅延した判断とでも呼びましょう。

たとえば、データベースのレコードを表として出力し始めたものの、出力を終えてはじめてデータベースにレコードがなかったと気づく場合です。そこで条件を終了タグ {/if} に置けば、レコードがないときには何も出力されません。

{if}
	<h1>データベースのレコード一覧</h1>

	<table>
	{foreach $resultSet as $row}
		...
	{/foreach}
	</table>
{/if isset($row)}

便利でしょう。

遅延した条件では {else} も使えますが、{elseif} は使えません。

{ifset} {elseifset}

{ifset block}も参照してください

変数(または複数の変数)が存在し、値が null でないかを判定するには {ifset $var} 条件を使います。実質的には PHP の if (isset($var)) と同じです。ほかのペアタグと同じく n:属性でも書けるので、その例を示しましょう。

<meta name="robots" content={$robots} n:ifset="$robots">

{ifchanged}

{ifchanged} は、ループ(foreach、for、while)の前回の反復から変数の値が変わったかを調べます。

タグに 1 つ以上の変数を渡すと、そのいずれかが変わったかを調べ、それに応じて内容を出力します。たとえば次の例は、名前を並べる途中で頭文字が変わるたびに、それを見出しとして出力します。

{foreach ($names|sort) as $name}
	{ifchanged $name[0]} <h2>{$name[0]}</h2> {/ifchanged}

	<p>{$name}</p>
{/foreach}

引数を渡さない場合は、レンダリングされた内容そのものが前回の状態と比べられます。つまり先ほどの例では、タグの引数を安心して省けます。もちろん n:属性も使えます。

{foreach ($names|sort) as $name}
	<h2 n:ifchanged>{$name[0]}</h2>

	<p>{$name}</p>
{/foreach}

{ifchanged} の中では {else} 節も使えます。

{switch} {case} {default}

値を複数の選択肢と比べます。PHP で知られる switch 文に似ていますが、Latte はそれを改良しています。

  • 厳密な比較(===)を使う
  • break が要らない

つまり PHP 8.0 で導入された match 構造にとてもよく似ています。

{switch $transport}
	{case train}
		電車で
	{case plane}
		飛行機で
	{default}
		それ以外
{/switch}

{case} 節にはカンマで区切って複数の値を書けます。

{switch $status}
{case $status::New}<b>新商品</b>
{case $status::Sold, $status::Unknown}<i>在庫なし</i>
{/switch}

ループ

Latte には PHP で知っているループがすべて揃っています。foreach、for、while です。

{foreach}

ループは PHP とまったく同じように書きます。

{foreach $langs as $code => $lang}
	<span>{$lang}</span>
{/foreach}

さらに、これから説明するいくつかの便利な機能があります。

たとえば Latte は、作られた変数が同じ名前のグローバル変数をうっかり上書きしていないかを確認します。$lang にページの現在の言語が入っているつもりでいたのに、foreach $langs as $lang がその変数を上書きしていた、といった事態から救ってくれます。

foreach ループは n:属性を使って、とてもきれいに簡潔に書けます。

<ul>
	<li n:foreach="$items as $item">{$item->name}</li>
</ul>

n:属性に inner- 接頭辞を付けられることをご存じですか。すると要素の内側の部分だけがループで繰り返されます。

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

つまり次のように出力されます。

<div>
	<h4>Foo</h4>
	<p>Lorem ipsum.</p>
	<h4>Bar</h4>
	<p>Sit dolor.</p>
</div>

{else}

foreach ループの中には {else} 節を書けます。その内容は、ループが空のときに表示されます。

<ul>
	{foreach $people as $person}
		<li>{$person->name}</li>
	{else}
		<li><em>申し訳ありません、このリストにユーザーはいません</em></li>
	{/foreach}
</ul>

$iterator

foreach ループの中で、Latte は $iterator 変数を作ります。これで進行中のループについて役立つ情報を得られます。

  • $iterator->first – これは最初の反復か?
  • $iterator->last – これは最後の反復か?
  • $iterator->counter – 反復のカウンタ。1 から始まります
  • $iterator->counter0 – 反復のカウンタ。0 から始まります
  • $iterator->odd – これは奇数回目の反復か?
  • $iterator->even – これは偶数回目の反復か?
  • $iterator->parent – 現在のイテレータを囲むイテレータ
  • $iterator->nextValue – ループの次の項目
  • $iterator->nextKey – ループの次の項目のキー
{foreach $rows as $row}
	{if $iterator->first}<table>{/if}

	<tr id="row-{$iterator->counter}">
		<td>{$row->name}</td>
		<td>{$row->email}</td>
	</tr>

	{if $iterator->last}</table>{/if}
{/foreach}

Latte は賢いので、$iterator->last は配列だけでなく、あらかじめ項目数が分からない一般的なイテレータ上のループでも働きます。

{first} {last} {sep}

これらのタグは {foreach} ループの中で使えます。{first} の内容は最初の反復のときにレンダリングされます。{last} の内容は……お分かりですね。そう、最後の反復のときです。実際にはこれらは {if $iterator->first}{if $iterator->last} の近道です。

これらのタグは n:属性としてもきれいに使えます。

{foreach $rows as $row}
	{first}<h1>名前の一覧</h1>{/first}

	<p>{$row->name}</p>

	<hr n:last>
{/foreach}

{sep} タグの内容は、その反復が最後でないときにレンダリングされるので、並べた項目のあいだのカンマのような区切りを出すのに向いています。

{foreach $items as $item} {$item} {sep}, {/sep} {/foreach}

なかなか実用的でしょう。

{iterateWhile}

条件が満たされているあいだ入れ子のループで反復することで、foreach ループでの繰り返し中に線形のデータをグループ化するのを簡単にします。詳しい説明をご覧ください

先ほどの例の {first}{last} を、きれいに置き換えることもできます。

{foreach $rows as $row}
	<table>

	{iterateWhile}
	<tr id="row-{$iterator->counter}">
		<td>{$row->name}</td>
		<td>{$row->email}</td>
	</tr>
	{/iterateWhile true}

	</table>
{/foreach}

batchgroupのフィルタも参照してください。

{for}

ループは PHP とまったく同じように書きます。

{for $i = 0; $i < 10; $i++}
	<span>項目 #{$i}</span>
{/for}

このタグは n:属性としても書けます。

<h1 n:for="$i = 0; $i < 10; $i++">{$i}</h1>

{while}

これも PHP とまったく同じように書きます。

{while $row = $result->fetch()}
	<span>{$row->title}</span>
{/while}

あるいは n:属性として。

<span n:while="$row = $result->fetch()">
	{$row->title}
</span>

条件を終了タグに書く形も可能で、PHP の do-while ループに対応します。

{while}
	<span>{$item->title}</span>
{/while $item = $item->getNext()}

{continueIf} {skipIf} {breakIf}

特別なタグ {continueIf ?}{breakIf ?} は、どんなループの制御にも使えます。条件が満たされると、それぞれ次の反復へ飛ぶか、ループを終えます。

{foreach $rows as $row}
	{continueIf $row->date < $now}
	{breakIf $row->parent === null}
	...
{/foreach}

{skipIf} タグは {continueIf} とよく似ていますが、$iterator->counter を増やしません。これにより、カウンタを出力しつつ一部の項目を飛ばすときに番号が飛ぶのを防げます。また、すべての項目が飛ばされた場合には {else} 節がレンダリングされます。

<ul>
	{foreach $people as $person}
		{skipIf $person->age < 18}
		<li>{$iterator->counter}. {$person->name}</li>
	{else}
		<li><em>申し訳ありません、このリストに成人はいません</em></li>
	{/foreach}
</ul>

{exitIf}

条件が満たされたとき、テンプレートやブロックのレンダリングを終えます(つまり「早期終了」です)。

{exitIf !$messages}

<h1>メッセージ</h1>
<div n:foreach="$messages as $message">
   {$message}
</div>

テンプレートの挿入

{include 'file.latte'}

{include block}{embed}も参照してください

{include} タグは指定したテンプレートを読み込んでレンダリングします。私たちの大好きな PHP でいえば、次のようなものです。

<?php include 'header.phtml'; ?>

挿入されたテンプレートは現在のコンテキストの変数にはアクセスできませんが、グローバル変数にはアクセスできます。

挿入するテンプレートには次のようにして変数を渡せます。

{include 'template.latte', foo: 'bar', id: 123}

テンプレート名には任意の PHP の式を使えます。

{include $someVar}
{include $ajax ? 'ajax.latte' : 'not-ajax.latte'}

テンプレートが存在するかは hasTemplate() 関数で調べられます。

挿入される内容はフィルタで加工できます。次の例はすべての HTML を取り除き、大文字小文字を整えます。

<title>{include 'heading.latte' |stripHtml|capitalize}</title>

既定では、ここにテンプレート継承は関わりません。挿入されるテンプレートの中でブロックを使うことはできますが、それが挿入先のテンプレートの対応するブロックを置き換えることはありません。挿入されるテンプレートは、ページやモジュールの独立した遮蔽された部分だと考えてください。この振る舞いは with blocks 修飾子で変えられます。

{include 'template.latte' with blocks}

タグに書いたファイル名とディスク上のファイルとの関係はローダーに依存します。

{sandbox}

エンドユーザーが作ったテンプレートを挿入する場合は、サンドボックス化を検討すべきです(詳しくはサンドボックスのドキュメントをご覧ください)。

{sandbox 'untrusted.latte', level: 3, data: $menu}

{block}

{block name}も参照してください

名前のないブロックは、テンプレートの一部にフィルタを適用する手段になります。たとえば不要な空白を取り除く spaceless フィルタを適用できます。

{block|spaceless}
<ul>
	<li>Hello World</li>
</ul>
{/block}

例外処理

{try}

このタグのおかげで、堅牢なテンプレートを作るのがきわめて簡単になります。

{try} ブロックのレンダリング中に例外が起きると、ブロック全体が破棄され、レンダリングはそのあとから続きます。

{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
{/try}

省略可能な {else} 節の内容は、例外が起きたときにだけレンダリングされます。

{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
	{else}
	<p>申し訳ありません、ツイートを読み込めませんでした。</p>
{/try}

このタグは n:属性としても書けます。

<ul n:try>
	...
</ul>

たとえばログ記録のために、独自の例外ハンドラを定義することもできます。

{rollback}

{try} ブロックは {rollback} を使って手動で止めて飛ばすこともできます。こうすれば、すべての入力データをあらかじめ確認する必要はなく、レンダリング中になってから、その対象をまったく描かないと決められます。

{try}
<ul>
	{foreach $people as $person}
 		{skipIf $person->age < 18}
 		<li>{$person->name}</li>
	{else}
		{rollback}
	{/foreach}
</ul>
{/try}

変数

{var} {default}

テンプレートで新しい変数を作るには {var} タグを使います。

{var $name = 'John Smith'}
{var $age = 27}

{* 複数の宣言 *}
{var $name = 'John Smith', $age = 27}

{default} タグも同じように働きますが、変数が存在しない場合にだけ作ります。変数がすでに存在していて値が null の場合、上書きはされません。

{default $lang = 'en'}

変数の型も指定できます。今のところ情報提供のためのもので、Latte はチェックしません。

{var string $name = $article->getTitle()}
{default int $id = 0}

{parameters}

関数が引数を宣言するのと同じように、テンプレートも先頭で変数を宣言できます。

{parameters
	$a,
	?int $b,
	int|string $c = 10
}

既定値を指定しない変数 $a$b は、自動的に既定値 null を持ちます。宣言された型は現時点では情報提供のためのもので、Latte はチェックしません。

宣言されたもの以外の変数はテンプレートに渡されません。この点が {default} タグとは異なります。

{capture}

出力を変数に取り込みます。

{capture $var}
<ul>
	<li>Hello World</li>
</ul>
{/capture}

<p>Captured: {$var}</p>

ほかのペアタグと同じく、このタグも n:属性として書けます。

<ul n:capture="$var">
	<li>Hello World</li>
</ul>

HTML の出力は、出力時に望まないエスケープを防ぐため、Latte\Runtime\Html オブジェクトとして $var 変数に格納されます。

そのほか

{contentType}

このタグで、テンプレートが表す内容の種類を指定します。選べるのは次のとおりです。

  • html(既定の種類)
  • xml
  • javascript
  • css
  • calendar(iCal)
  • text

これを使うことが重要なのは、コンテキストに応じたエスケープを設定するからで、そうしてはじめて Latte は正しくエスケープできます。たとえば {contentType xml} は XML モードに切り替え、{contentType text} はエスケープを完全に無効にします。

パラメータが application/xml のような完全な MIME タイプなら、Content-Type の HTTP ヘッダーもブラウザに送ります。

{contentType application/xml}
<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>RSS feed</title>
		<item>
			...
		</item>
	</channel>
</rss>

{debugbreak}

プログラムの実行を止める地点を指定します。デバッグの目的で使い、プログラマーが実行時の環境を調べ、コードが期待どおりに動いているか確かめられます。Xdebugに対応しています。いつプログラムを止めるかを決める条件も付けられます。

{debugbreak}                {* プログラムを止める *}

{debugbreak $counter == 1}  {* 条件が満たされたらプログラムを止める *}

{do}

PHP のコードを実行し、何も出力しません。ほかのすべてのタグと同じく、PHP のコードとはひとつの式のことです。PHP の制限をご覧ください。

{do $num++}

{dump}

変数や現在のコンテキストをダンプします。

{dump $name} {* $name 変数をダンプする *}

{dump}       {* 現在定義されているすべての変数をダンプする *}

Tracyライブラリが必要です。

{php}

既定では {php}{do}の古い別名として働き、ひとつの式だけを評価します。任意の PHP コードを実行するには、RawPhpExtension拡張でこのタグを有効にする必要があります。

{spaceless}

出力から不要な空白を取り除きます。spaceless フィルタと同じように働きます。

{spaceless}
	<ul>
		<li>Hello</li>
	</ul>
{/spaceless}

次を生成します。

<ul> <li>Hello</li> </ul>

このタグは n:属性としても書けます。

{syntax}

Latte のタグは単一の波かっこで囲まなければならないわけではありません。実行時であっても、別の区切りを選べます。それを行うのが {syntax …} で、パラメータには次のものを指定できます。

  • double: {{...}}
  • off: Latte のタグ処理を完全に無効にする

n:属性を使えば、たとえば JavaScript のひとつのブロックについてだけ Latte を無効にできます。

<script n:syntax="off">
	var obj = {var: 123}; // これはもうタグではありません
</script>

Latte は JavaScript の中でもとても快適に使えます。この例のように { の直後に文字が続く書き方だけ避けてください。JavaScript や CSS の中の Latteをご覧ください。

{syntax off}(n:属性ではなくタグのほう)で Latte を無効にすると、{/syntax} までのすべてのタグを厳密に無視します。

{trace}

Latte\RuntimeException 例外を投げます。そのスタックトレースはテンプレートの流儀に沿ったものです。つまり関数やメソッドの呼び出しではなく、ブロックの呼び出しやテンプレートの挿入が並びます。Tracyのように投げられた例外を見やすく表示するツールを使っていれば、渡されたすべての引数を含む呼び出しスタックがはっきり分かります。

HTML コーダー向けの補助

n:class

Latte 3.1 以降、標準の HTML の class 属性が同じ機能を備えました。ですから n:class を使う必要はもうありません。

n:class のおかげで、HTML の class 属性を望みどおりに生成するのがとても簡単になります。

例: アクティブな要素に active クラスを付けたいとします。

{foreach $items as $item}
	<a n:class="$item->isActive() ? active">...</a>
{/foreach}

さらに、最初の要素には firstmain のクラスを付けたいとします。

{foreach $items as $item}
	<a n:class="$item->isActive() ? active, $iterator->first ? 'first main'">...</a>
{/foreach}

そしてすべての要素に list-item クラスを付けたいとします。

{foreach $items as $item}
	<a n:class="$item->isActive() ? active, $iterator->first ? 'first main', list-item">...</a>
{/foreach}

驚くほど簡単でしょう。

n:attr

n:attr 属性は、classと同じ優雅さで任意の HTML 属性を生成できます。

{foreach $data as $item}
	<input type="checkbox" n:attr="value: $item->getValue(), checked: $item->isActive()">
{/foreach}

返される値に応じて、たとえば次のように出力します。

<input type="checkbox">

<input type="checkbox" value="Hello">

<input type="checkbox" value="Hello" checked>

null の値を落とす、classstyle に配列を渡すといった Latte 3.1 のスマート属性の機能は、n:attr の中でも働きます。

<div n:attr="class: [a, b], title: $title"></div>

n:tag

n:tag 属性は HTML 要素の名前を動的に変えられます。

<h1 n:tag="$heading" class="main">{$title}</h1>

$heading === null なら <h1> タグはそのまま出力されます。そうでなければ要素名が変数の値に変わるので、$heading === 'h3' なら次のように書き出されます。

<h3 class="main">...</h3>

Latte は安全なテンプレートシステムなので、新しいタグ名が正しいこと、望ましくない値や悪意ある値を含まないことを確認します。

n:ifcontent

空の HTML 要素、つまり空白しか含まない要素が出力されるのを防ぎます。

<div>
	<div class="error" n:ifcontent>{$error}</div>
</div>

変数 $error の値に応じて、次のように出力されます。

{* $error = '' *}
<div>
</div>

{* $error = 'Required' *}
<div>
	<div class="error">Required</div>
</div>

翻訳

翻訳のタグを使えるようにするには、トランスレーターを有効にする必要があります。翻訳には translate フィルタも使えます。

{_...}

値をほかの言語に翻訳します。

<a href="basket">{_'カート'}</a>
<span>{_$item}</span>

トランスレーターにはほかのパラメータも渡せます。

<a href="basket">{_'カート', domain: order}</a>

{translate}

テンプレートの一部を翻訳します。

<h1>{translate}注文{/translate}</h1>

{translate domain: order}Lorem ipsum ...{/translate}

このタグは n:属性としても書けて、要素の内側を翻訳します。

<h1 n:translate>注文</h1>