Nette Documentation Preview

syntax
Latte Tags
**********

.[perex]
Eine Übersicht und Beschreibung aller Latte-Template-System-Tags, die standardmäßig zur Verfügung stehen.

.[table-latte-tags language-latte]
|## Ausgabe
| `{$var}`, `{...}` oder `{=...}`  | [gibt eine escaped Variable oder einen Ausdruck aus|#Ausgabe]
| `{$var\|filter}`                 | [gibt mit Verwendung von Filtern aus|#Filter]
| `{l}` oder `{r}`                 | gibt das Zeichen `{` oder `}` aus

.[table-latte-tags language-latte]
|## Bedingungen
| `{if}` … `{elseif}` … `{else}` … `{/if}`    | [if-Bedingung|#if-elseif-else]
| `{ifset}` … `{elseifset}` … `{/ifset}`      | [ifset-Bedingung|#ifset-elseifset]
| `{ifchanged}` … `{/ifchanged}`              | [Test, ob eine Änderung aufgetreten ist|#ifchanged]
| `{switch}` `{case}` `{default}` `{/switch}` | [switch-Bedingung|#switch-case-default]
| `n:else`                                    | [alternativer Inhalt für Bedingungen|#n:else]

.[table-latte-tags language-latte]
|## Schleifen
| `{foreach}` … `{/foreach}`     | [#foreach]
| `{for}` … `{/for}`             | [#for]
| `{while}` … `{/while}`         | [#while]
| `{continueIf $cond}`           | [mit der nächsten Iteration fortfahren|#continueif-skipif-breakif]
| `{skipIf $cond}`               | [Iteration überspringen|#continueif-skipif-breakif]
| `{breakIf $cond}`              | [Schleife abbrechen|#continueif-skipif-breakif]
| `{exitIf $cond}`               | [vorzeitige Beendigung|#exitif]
| `{first}` … `{/first}`         | [ist es der erste Durchlauf?|#first-last-sep]
| `{last}` … `{/last}`           | [ist es der letzte Durchlauf?|#first-last-sep]
| `{sep}` … `{/sep}`             | [wird noch ein Durchlauf folgen?|#first-last-sep]
| `{iterateWhile}` … `{/iterateWhile}` | [strukturiertes foreach|#iterateWhile]
| `$iterator`                    | [spezielle Variable innerhalb von foreach|#$iterator]

.[table-latte-tags language-latte]
|## Einbindung weiterer Templates
| `{include 'file.latte'}`       | [lädt ein Template aus einer anderen Datei|#include]
| `{sandbox 'file.latte'}`       | [lädt ein Template im Sandbox-Modus|#sandbox]

.[table-latte-tags language-latte]
|## Blöcke, Layouts, Template-Vererbung
| `{block}`                      | [anonymer Block|#block]
| `{block blockname}`            | [definiert einen Block|template-inheritance#blocks]
| `{define blockname}`           | [definiert einen Block zur späteren Verwendung|template-inheritance#definitions]
| `{include blockname}`          | [Darstellung eines Blocks|template-inheritance#printing-blocks]
| `{include blockname from 'file.latte'}` | [stellt einen Block aus einer Datei dar|template-inheritance#printing-blocks]
| `{import 'file.latte'}`        | [lädt Blöcke aus einem Template|template-inheritance#horizontal-reuse]
| `{layout 'file.latte'}` / `{extends}` | [bestimmt die Layout-Datei|template-inheritance#layout-inheritance]
| `{embed}` … `{/embed}`         | [lädt ein Template oder einen Block und ermöglicht das Überschreiben von Blöcken|template-inheritance#unit-inheritance]
| `{ifset blockname}` … `{/ifset}`   | [Bedingung, ob ein Block existiert|template-inheritance#checking-block-existence]

.[table-latte-tags language-latte]
|## Ausnahmebehandlung
| `{try}` … `{else}` … `{/try}`  | [Abfangen von Ausnahmen|#try]
| `{rollback}`                   | [Verwerfen eines try-Blocks|#rollback]

.[table-latte-tags language-latte]
|## Variablen
| `{var $foo = value}`           | [erstellt eine Variable|#var-default]
| `{default $foo = value}`       | [erstellt eine Variable, wenn sie nicht existiert|#var-default]
| `{parameters}`                 | [deklariert Variablen, Typen und Standardwerte|#parameters]
| `{capture}` … `{/capture}`     | [erfasst einen Block in eine Variable|#capture]

.[table-latte-tags language-latte]
|## Typen
| `{varType}`                    | [deklariert den Typ einer Variable|type-system#varType]
| `{varPrint}`                   | [schlägt Typen für Variablen vor|type-system#varPrint]
| `{templateType}`               | [deklariert Variablentypen basierend auf einer Klasse|type-system#templateType]
| `{templatePrint}`              | [schlägt eine Klasse mit Variablentypen vor|type-system#templatePrint]

.[table-latte-tags language-latte]
|## Übersetzungen
| `{_...}`                       | [gibt eine Übersetzung aus|#übersetzungen]
| `{translate}` … `{/translate}` | [übersetzt den Inhalt|#übersetzungen]

.[table-latte-tags language-latte]
|## Sonstiges
| `{contentType}`                | [schaltet das Escaping um und sendet einen HTTP-Header|#contenttype]
| `{debugbreak}`                 | [platziert einen Breakpoint im Code|#debugbreak]
| `{do}`                         | [führt Code aus, gibt aber nichts aus|#do]
| `{dump}`                       | [dumpt Variablen in die Tracy Bar|#dump]
| `{php}`                        | [führt beliebigen PHP-Code aus|#php]
| `{spaceless}` … `{/spaceless}` | [entfernt überflüssige Leerzeichen|#spaceless]
| `{syntax}`                     | [Änderung der Syntax zur Laufzeit|#syntax]
| `{trace}`                      | [zeigt den Stack-Trace an|#trace]

.[table-latte-tags language-latte]
|## Helfer für HTML-Codierer
| `n:class`                      | [dynamische Schreibweise des HTML-Attributs class|#n:class]
| `n:attr`                       | [dynamische Schreibweise beliebiger HTML-Attribute|#n:attr]
| `n:tag`                        | [dynamische Schreibweise des HTML-Element-Namens|#n:tag]
| `n:ifcontent`                  | [lässt einen leeren HTML-Tag aus|#n:ifcontent]

.[table-latte-tags language-latte]
|## Nur im Nette Framework verfügbar
| `n:href`                       | [Link, der in HTML-Elementen `<a>` verwendet wird|application:creating-links#In the Presenter Template]
| `{link}`                       | [gibt einen Link aus|application:creating-links#In the Presenter Template]
| `{plink}`                      | [gibt einen Link zu einem Presenter aus|application:creating-links#In the Presenter Template]
| `{control}`                    | [rendert eine Komponente|application:components#Rendering]
| `{snippet}` … `{/snippet}`     | [ein Snippet, das per AJAX gesendet werden kann|application:ajax#snippets-in-latte]
| `{snippetArea}`                | [Wrapper für Snippets|application:ajax#snippet-areas]
| `{cache}` … `{/cache}`         | [cached einen Teil des Templates|caching:#caching-in-latte]

.[table-latte-tags language-latte]
|## Nur mit Nette Forms verfügbar
| `{form}` … `{/form}`           | [rendert Formular-Tags|forms:rendering#form]
| `{label}` … `{/label}`         | [rendert ein Label für ein Formularelement|forms:rendering#label-input]
| `{input}`                      | [rendert ein Formularelement|forms:rendering#label-input]
| `{inputError}`                 | [gibt eine Fehlermeldung für ein Formularelement aus|forms:rendering#inputError]
| `n:name`                       | [aktiviert ein Formularelement|forms:rendering#n:name]
| `{formContainer}` … `{/formContainer}` | [Zeichnen eines Formular-Containers|forms:rendering#special-cases]


Ausgabe .[#toc-printing]
========================


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

In Latte wird das Tag `{=...}` verwendet, um einen beliebigen Ausdruck auszugeben. Latte legt Wert auf Ihren Komfort, daher ist es nicht nötig, das Gleichheitszeichen zu schreiben, wenn der Ausdruck mit einer Variable oder einem Funktionsaufruf beginnt. Das bedeutet in der Praxis, dass es fast nie notwendig ist, es zu schreiben:

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

Als Ausdruck können Sie alles schreiben, was Sie aus PHP kennen. Sie müssen einfach keine neue Sprache lernen. Zum Beispiel:


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

Bitte suchen Sie in dem vorherigen Beispiel keinen Sinn, aber wenn Sie einen finden sollten, schreiben Sie uns :-)


Ausgabe escapen .[#toc-escaping-output]
---------------------------------------

Was ist die wichtigste Aufgabe eines Template-Systems? Sicherheitslücken zu verhindern. Und genau das macht Latte immer, wenn Sie etwas ausgeben. Es escaped es automatisch:

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

Um genau zu sein, verwendet Latte kontextsensitives Escaping, was so wichtig und einzigartig ist, dass wir ihm [ein eigenes Kapitel|safety-first#context-aware-escaping] gewidmet haben.

Und was ist, wenn Sie HTML-codierten Inhalt aus einer vertrauenswürdigen Quelle ausgeben? Dann kann das Escaping einfach deaktiviert werden:

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

.[warning]
Eine falsche Verwendung des `noescape`-Filters kann zu einer XSS-Schwachstelle führen! Verwenden Sie ihn niemals, wenn Sie sich nicht **absolut sicher** sind, was Sie tun, und dass die ausgegebene Zeichenkette aus einer vertrauenswürdigen Quelle stammt.


Ausgabe in JavaScript .[#toc-printing-in-javascript]
----------------------------------------------------

Dank des kontextsensitiven Escapings ist es wunderbar einfach, Variablen innerhalb von JavaScript auszugeben, und Latte kümmert sich um das korrekte Escaping.

Die Variable muss nicht unbedingt ein String sein, es wird jeder Datentyp unterstützt, der dann als JSON kodiert wird:

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

Erzeugt:

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

Das ist auch der Grund, warum **keine Anführungszeichen** um die Variable geschrieben werden: Latte fügt sie bei Strings selbst hinzu. Und wenn Sie eine String-Variable in einen anderen String einfügen möchten, verbinden Sie sie einfach:

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

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

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


Filter .[#toc-filters]
----------------------

Der ausgegebene Ausdruck kann durch einen [Filter|syntax#filters] modifiziert werden. So können wir zum Beispiel eine Zeichenkette in Großbuchstaben umwandeln und auf maximal 30 Zeichen kürzen:

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

Filter können auch auf Teile eines Ausdrucks auf folgende Weise angewendet werden:

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


Bedingungen .[#toc-conditions]
==============================


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

Bedingungen verhalten sich genauso wie ihre Pendants in PHP. Sie können in ihnen die gleichen Ausdrücke verwenden, die Sie aus PHP kennen, Sie müssen keine neue Sprache lernen.

```latte
{if $product->inStock > Stock::Minimum}
	Auf Lager
{elseif $product->isOnWay()}
	Unterwegs
{else}
	Nicht verfügbar
{/if}
```

Wie jedes Paar-Tag kann auch das Paar `{if} ... {/if}` in Form eines [n:Attributs|syntax#n:attributes] geschrieben werden, zum Beispiel:

```latte
<p n:if="$count > 0">{$count} Artikel auf Lager</p>
```

Wussten Sie, dass Sie n:Attribute mit dem Präfix `tag-` versehen können? Dann bezieht sich die Bedingung nur auf die Ausgabe der HTML-Tags, und der Inhalt dazwischen wird immer ausgegeben:

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

{* gibt 'Hello' aus, wenn $clickable falsch ist *}
{* gibt '<a href="...">Hello</a>' aus, wenn $clickable wahr ist *}
```

Göttlich.


`n:else` .{data-version:3.0.11}
-------------------------------

Wenn Sie die Bedingung `{if} ... {/if}` in Form eines [n:Attributs|syntax#n:attributes] schreiben, haben Sie die Möglichkeit, eine alternative Verzweigung mit `n:else` anzugeben:

```latte
<strong n:if="$count > 0">{$count} Artikel auf Lager</strong>

<em n:else>nicht verfügbar</em>
```

Das Attribut `n:else` kann auch in Kombination mit [`n:ifset` |#ifset-elseifset], [`n:foreach` |#foreach], [`n:try` |#try], [`n:ifcontent` |#n:ifcontent] und [`n:ifchanged` |#ifchanged] verwendet werden.


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

Es mag Sie überraschen, dass der Ausdruck in der Bedingung `{if}` auch im schließenden Tag angegeben werden kann. Dies ist nützlich in Situationen, in denen wir beim Öffnen der Bedingung ihren Wert noch nicht kennen. Nennen wir es eine verzögerte Entscheidung.

Zum Beispiel beginnen wir mit der Ausgabe einer Tabelle mit Datensätzen aus der Datenbank und erst nach Abschluss der Ausgabe stellen wir fest, dass kein Datensatz in der Datenbank vorhanden war. Also setzen wir eine Bedingung in das schließende `{/if}`-Tag, und wenn kein Datensatz vorhanden ist, wird nichts davon ausgegeben:

```latte
{if}
	<h1>Ausgabe von Zeilen aus der Datenbank</h1>

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

Clever, nicht wahr?

In einer verzögerten Bedingung kann auch `{else}` verwendet werden, aber nicht `{elseif}`.


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

.[note]
Siehe auch [`{ifset block}` |template-inheritance#checking-block-existence]

Mit der Bedingung `{ifset $var}` können wir überprüfen, ob eine Variable (oder mehrere Variablen) existiert und einen nicht-null-Wert hat. Es ist im Grunde dasselbe wie `if (isset($var))` in PHP. Wie jedes Paar-Tag kann es auch in Form eines [n:Attributs|syntax#n:attributes] geschrieben werden, also zeigen wir es als Beispiel:

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


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

`{ifchanged}` überprüft, ob sich der Wert einer Variable seit der letzten Iteration in einer Schleife (foreach, for oder while) geändert hat.

Wenn wir eine oder mehrere Variablen im Tag angeben, wird überprüft, ob sich eine von ihnen geändert hat, und dementsprechend wird der Inhalt ausgegeben. Das folgende Beispiel gibt den ersten Buchstaben des Namens als Überschrift aus, jedes Mal wenn er sich bei der Ausgabe der Namen ändert:

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

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

Wenn wir jedoch kein Argument angeben, wird der gerenderte Inhalt im Vergleich zu seinem vorherigen Zustand überprüft. Das bedeutet, dass wir im vorherigen Beispiel das Argument im Tag weglassen können. Und natürlich können wir auch ein [n:Attribut|syntax#n:attributes] verwenden:

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

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

Innerhalb von `{ifchanged}` kann auch eine `{else}`-Klausel verwendet werden.


`{switch}` `{case}` `{default}`
-------------------------------
Vergleicht einen Wert mit mehreren Möglichkeiten. Es ist ähnlich wie die bedingte Anweisung `switch`, die Sie aus PHP kennen. Latte verbessert sie jedoch:

- es verwendet einen strikten Vergleich (`===`)
- es benötigt kein `break`

Es ist also das genaue Äquivalent zur `match`-Struktur, die mit PHP 8.0 eingeführt wurde.

```latte
{switch $transport}
	{case train}
		Mit dem Zug
	{case plane}
		Mit dem Flugzeug
	{default}
		Anderweitig
{/switch}
```

Die `{case}`-Klausel kann mehrere durch Kommas getrennte Werte enthalten:

```latte
{switch $status}
{case $status::New}<b>neuer Artikel</b>
{case $status::Sold, $status::Unknown}<i>nicht verfügbar</i>
{/switch}
```


Schleifen .[#toc-loops]
=======================

In Latte finden Sie alle Schleifen, die Sie aus PHP kennen: foreach, for und while.


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

Wir schreiben die Schleife genauso wie in PHP:

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

Zusätzlich hat sie einige nützliche Funktionen, über die wir jetzt sprechen werden.

Latte überprüft zum Beispiel, ob erstellte Variablen versehentlich globale Variablen mit demselben Namen überschreiben. Das rettet Situationen, in denen Sie davon ausgehen, dass `$lang` die aktuelle Sprache der Seite ist, und nicht bemerken, dass `foreach $langs as $lang` diese Variable überschrieben hat.

Die foreach-Schleife kann auch sehr elegant und kompakt als [n:Attribut|syntax#n:attributes] geschrieben werden:

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

Wussten Sie, dass Sie n:Attribute mit dem Präfix `inner-` versehen können? Dann wird nur der Inhalt des Elements in der Schleife wiederholt:

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

Dies wird also etwas wie folgendes ausgeben:

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


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

Innerhalb einer `foreach`-Schleife kann eine `{else}`-Klausel angegeben werden, deren Inhalt angezeigt wird, wenn die Schleife leer ist:

```latte
<ul>
	{foreach $people as $person}
		<li>{$person->name}</li>
	{else}
		<li><em>Leider sind in dieser Liste keine Benutzer</em></li>
	{/foreach}
</ul>
```


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

Innerhalb einer `foreach`-Schleife erstellt Latte eine Variable `$iterator`, mit der wir nützliche Informationen über die laufende Schleife abrufen können:

- `$iterator->first` - ist dies der erste Durchlauf?
- `$iterator->last` - ist dies der letzte Durchlauf?
- `$iterator->counter` - der wievielte Durchlauf ist es, gezählt ab eins?
- `$iterator->counter0` - der wievielte Durchlauf ist es, gezählt ab null?
- `$iterator->odd` - ist dies ein ungerader Durchlauf?
- `$iterator->even` - ist dies ein gerader Durchlauf?
- `$iterator->parent` - der Iterator, der den aktuellen umgibt
- `$iterator->nextValue` - der nächste Eintrag in der Schleife
- `$iterator->nextKey` - der Schlüssel des nächsten Eintrags in der Schleife


```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 ist schlau und `$iterator->last` funktioniert nicht nur bei Arrays, sondern auch wenn die Schleife über einen allgemeinen Iterator läuft, bei dem die Anzahl der Elemente nicht im Voraus bekannt ist.


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

Diese Tags können innerhalb einer `{foreach}`-Schleife verwendet werden. Der Inhalt von `{first}` wird gerendert, wenn es sich um den ersten Durchlauf handelt.
Der Inhalt von `{last}` wird gerendert ... können Sie es erraten? Ja, wenn es sich um den letzten Durchlauf handelt. Es handelt sich eigentlich um Abkürzungen für `{if $iterator->first}` und `{if $iterator->last}`.

Die Tags können auch elegant als [n:Attribute|syntax#n:attributes] verwendet werden:

```latte
{foreach $rows as $row}
	{first}<h1>Liste der Namen</h1>{/first}

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

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

Der Inhalt des `{sep}`-Tags wird gerendert, wenn der Durchlauf nicht der letzte ist. Es eignet sich also zum Rendern von Trennzeichen, zum Beispiel Kommas zwischen ausgegebenen Elementen:

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

Das ist ziemlich praktisch, nicht wahr?


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

Vereinfacht die Gruppierung linearer Daten während der Iteration in einer foreach-Schleife, indem die Iteration in einer verschachtelten Schleife durchgeführt wird, solange eine Bedingung erfüllt ist. [Lesen Sie die detaillierte Anleitung|cookbook/grouping].

Es kann auch elegant `{first}` und `{last}` im obigen Beispiel ersetzen:

```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}
```

Siehe auch die Filter [batch|filters#batch] und [group|filters#group].


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

Wir schreiben die Schleife genauso wie in PHP:

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

Das Tag kann auch als [n:Attribut|syntax#n:attributes] verwendet werden:

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


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

Wir schreiben die Schleife wieder genauso wie in PHP:

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

Oder als [n:Attribut|syntax#n:attributes]:

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

Eine Variante mit der Bedingung im schließenden Tag ist ebenfalls möglich, die der do-while-Schleife in PHP entspricht:

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


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

Zur Steuerung jeder Schleife können die Tags `{continueIf ?}` und `{breakIf ?}` verwendet werden, die zum nächsten Element übergehen bzw. die Schleife beenden, wenn eine Bedingung erfüllt ist:

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


Das `{skipIf}`-Tag ist sehr ähnlich wie `{continueIf}`, erhöht aber nicht den Zähler `$iterator->counter`, so dass, wenn wir ihn ausgeben und gleichzeitig einige Elemente überspringen, keine Lücken in der Nummerierung entstehen. Außerdem wird die `{else}`-Klausel gerendert, wenn wir alle Elemente überspringen.

```latte
<ul>
	{foreach $people as $person}
		{skipIf $person->age < 18}
		<li>{$iterator->counter}. {$person->name}</li>
	{else}
		<li><em>Leider gibt es keine Erwachsenen in dieser Liste</em></li>
	{/foreach}
</ul>
```


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

Beendet das Rendern des Templates oder Blocks, wenn eine Bedingung erfüllt ist (sogenannter "early exit").

```latte
{exitIf !$messages}

<h1>Nachrichten</h1>
<div n:foreach="$messages as $message">
   {$message}
</div>
```


Einbindung von Templates .[#toc-including-templates]
====================================================


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

.[note]
Siehe auch [`{include block}` |template-inheritance#printing-blocks]

Das `{include}`-Tag lädt und rendert das angegebene Template. Wenn wir in der Sprache unserer Lieblingssprache PHP sprechen würden, wäre es so etwas wie:

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

Eingebundene Templates haben keinen Zugriff auf die Variablen des aktiven Kontexts, sie haben nur Zugriff auf globale Variablen.

Variablen können auf diese Weise an das eingebundene Template übergeben werden:

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

Der Name des Templates kann ein beliebiger PHP-Ausdruck sein:

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

Der eingebundene Inhalt kann mit [Filtern|syntax#Filters] modifiziert werden. Das folgende Beispiel entfernt das gesamte HTML und passt die Groß-/Kleinschreibung an:

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

Standardmäßig spielt die [Template-Vererbung|template-inheritance] in diesem Fall keine Rolle. Auch wenn wir in dem eingebundenen Template Blöcke verwenden können, werden die entsprechenden Blöcke in dem Template, in das eingebunden wird, nicht ersetzt. Denken Sie an eingebundene Templates als separate, abgeschirmte Teile von Seiten oder Modulen. Dieses Verhalten kann mit dem Modifikator `with blocks` geändert werden:

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

Die Beziehung zwischen dem im Tag angegebenen Dateinamen und der Datei auf der Festplatte ist eine Angelegenheit des [Loaders|extending-latte#Loaders].


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

Bei der Einbindung eines vom Endbenutzer erstellten Templates sollten Sie den Sandbox-Modus in Betracht ziehen (weitere Informationen finden Sie in der [Sandbox-Dokumentation |sandbox]):

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


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

.[note]
Siehe auch [`{block name}` |template-inheritance#blocks]

Namenlose Blöcke dienen als Möglichkeit, [Filter|syntax#Filters] auf einen Teil des Templates anzuwenden. Zum Beispiel kann auf diese Weise der [strip|filters#strip]-Filter angewendet werden, der überflüssige Leerzeichen entfernt:

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


Ausnahmebehandlung .[#toc-exception-handling]
=============================================


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

Dank dieses Tags ist es extrem einfach, robuste Templates zu erstellen.

Wenn während des Renderns eines `{try}`-Blocks eine Ausnahme auftritt, wird der gesamte Block verworfen und das Rendering wird danach fortgesetzt:

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

Der Inhalt in der optionalen `{else}`-Klausel wird nur gerendert, wenn eine Ausnahme auftritt:

```latte
{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
	{else}
	<p>Es tut uns leid, die Tweets konnten nicht geladen werden.</p>
{/try}
```

Das Tag kann auch als [n:Attribut|syntax#n:attributes] verwendet werden:

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

Es ist auch möglich, einen eigenen [Handler für Ausnahmen|develop#exception handler] zu definieren, zum Beispiel für Logging-Zwecke.


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

Ein `{try}`-Block kann auch manuell mit `{rollback}` gestoppt und übersprungen werden. Dadurch müssen Sie nicht alle Eingabedaten im Voraus überprüfen und können während des Renderings entscheiden, dass Sie das Objekt überhaupt nicht rendern möchten:

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


Variablen .[#toc-variables]
===========================


`{var}` `{default}`
-------------------

Neue Variablen werden im Template mit dem Tag `{var}` erstellt:

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

{* Mehrfachdeklaration *}
{var $name = 'John Smith', $age = 27}
```

Das Tag `{default}` funktioniert ähnlich, mit dem Unterschied, dass es Variablen nur dann erstellt, wenn sie noch nicht existieren. Wenn eine Variable bereits existiert und `null` enthält, wird sie nicht überschrieben:

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

Sie können auch [Variablentypen|type-system] angeben. Diese sind derzeit informativ und werden von Latte nicht überprüft.

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


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

So wie eine Funktion ihre Parameter deklariert, kann auch ein Template am Anfang seine Variablen deklarieren:

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

Variablen `$a` und `$b` ohne angegebenen Standardwert haben automatisch den Standardwert `null`. Die deklarierten Typen sind derzeit informativ und werden von Latte nicht überprüft.

Andere als die deklarierten Variablen werden nicht in das Template übertragen. Dies unterscheidet es vom Tag `{default}`.


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

Erfasst die Ausgabe in eine Variable:

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

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

Das Tag kann, wie jedes Paar-Tag, auch als [n:Attribut|syntax#n:Attribute] geschrieben werden:

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

Die HTML-Ausgabe wird in der Variable `$var` als `Latte\Runtime\Html`-Objekt gespeichert, um [unerwünschtes Escaping |develop#disabling-auto-escaping-of-variable] beim Ausgeben zu verhindern.


Sonstiges .[#toc-others]
========================


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

Mit diesem Tag geben Sie an, welchen Inhaltstyp das Template darstellt. Die Optionen sind:

- `html` (Standardtyp)
- `xml`
- `javascript`
- `css`
- `calendar` (iCal)
- `text`

Seine Verwendung ist wichtig, da es das [kontextsensitive Escaping |safety-first#context-aware-escaping] festlegt und nur so richtig escapen kann. Zum Beispiel schaltet `{contentType xml}` in den XML-Modus um, `{contentType text}` schaltet das Escaping komplett aus.

Wenn der Parameter ein vollständiger MIME-Typ ist, wie zum Beispiel `application/xml`, wird zusätzlich der HTTP-Header `Content-Type` an den Browser gesendet:

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


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

Markiert eine Stelle, an der die Programmausführung angehalten und der Debugger gestartet wird, damit der Programmierer die Laufzeitumgebung inspizieren und überprüfen kann, ob das Programm wie erwartet funktioniert. Es unterstützt [Xdebug |https://xdebug.org/]. Eine Bedingung kann hinzugefügt werden, die bestimmt, wann das Programm angehalten werden soll.

```latte
{debugbreak}                {* hält das Programm an *}

{debugbreak $counter == 1}  {* hält das Programm an, wenn die Bedingung erfüllt ist *}
```


`{do}`
------

Führt PHP-Code aus und gibt nichts aus. Wie bei allen anderen Tags mit PHP-Code handelt es sich um einen einzelnen Ausdruck, siehe [PHP-Einschränkungen |syntax#PHP Limitations in Latte].

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


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

Gibt eine Variable oder den aktuellen Kontext aus.

```latte
{dump $name} {* Gibt die Variable $name aus *}

{dump}       {* Gibt alle aktuell definierten Variablen aus *}
```

.[caution]
Erfordert die [Tracy|tracy:]-Bibliothek.


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

Ermöglicht die Ausführung beliebigen PHP-Codes. Das Tag muss durch die [RawPhpExtension |develop#RawPhpExtension] aktiviert werden.


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

Entfernt überflüssige Leerzeichen aus der Ausgabe. Funktioniert ähnlich wie der Filter [spaceless|filters#spaceless].

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

Erzeugt

```latte
<ul> <li>Hallo</li> </ul>
```

Das Tag kann auch als [n:Attribut|syntax#n:attributes] geschrieben werden.


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

Latte-Tags müssen nicht nur durch einfache geschweifte Klammern begrenzt sein. Wir können auch einen anderen Begrenzer wählen, sogar zur Laufzeit. Dafür wird `{syntax …}` verwendet, wobei als Parameter angegeben werden kann:

- double: `{{...}}`
- off: schaltet die Verarbeitung von Latte-Tags komplett aus

Mit Hilfe von n:Attributen kann Latte zum Beispiel nur für einen JavaScript-Block ausgeschaltet werden:

```latte
<script n:syntax="off">
	var obj = {var: 123}; // dies ist kein Tag mehr
</script>
```

Latte kann sehr bequem auch innerhalb von JavaScript verwendet werden, man muss nur Konstruktionen wie in diesem Beispiel vermeiden, bei denen direkt nach `{` ein Buchstabe folgt, siehe [Latte innerhalb von JavaScript oder CSS|recipes#Latte inside JavaScript or CSS].

Wenn Sie Latte mit `{syntax off}` ausschalten (d.h. mit einem Tag, nicht mit einem n:Attribut), wird es konsequent alle Tags bis `{/syntax}` ignorieren.


{trace}
-------

Wirft eine `Latte\RuntimeException`, deren Stack-Trace im Geiste der Templates ist. Anstelle von Funktions- und Methodenaufrufen enthält er also Blockaufrufe und Template-Einbindungen. Wenn Sie ein Tool zur übersichtlichen Anzeige von geworfenen Ausnahmen verwenden, wie zum Beispiel [Tracy|tracy:], wird Ihnen der Call Stack einschließlich aller übergebenen Argumente übersichtlich angezeigt.


Helfer für HTML-Codierer .[#toc-html-tag-helpers]
=================================================


n:class
-------

Dank `n:class` können Sie sehr einfach das HTML-Attribut `class` genau nach Ihren Vorstellungen generieren.

Beispiel: Ich brauche, dass das aktive Element die Klasse `active` hat:

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

Und weiter, dass das erste Element die Klassen `first` und `main` hat:

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

Und alle Elemente sollen die Klasse `list-item` haben:

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

Unglaublich einfach, nicht wahr?


n:attr
------

Das Attribut `n:attr` kann mit der gleichen Eleganz wie [n:class|#n:class] beliebige HTML-Attribute generieren.

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

Abhängig von den zurückgegebenen Werten wird zum Beispiel Folgendes ausgegeben:

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

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

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


n:tag
-----

Das Attribut `n:tag` kann den Namen des HTML-Elements dynamisch ändern.

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

Wenn `$heading === null` ist, wird der Tag `<h1>` unverändert ausgegeben. Andernfalls wird der Name des Elements auf den Wert der Variable geändert, so dass für `$heading === 'h3'` Folgendes ausgegeben wird:

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

Da Latte ein sicheres Template-System ist, überprüft es, ob der neue Tag-Name gültig ist und keine unerwünschten oder schädlichen Werte enthält.


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

Verhindert, dass ein leeres HTML-Element ausgegeben wird, d.h. ein Element, das nichts außer Leerzeichen enthält.

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

Gibt abhängig vom Wert der Variable `$error` aus:

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

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


Übersetzungen .[#toc-translation]
=================================

Damit die Übersetzungs-Tags funktionieren, muss der [Übersetzer aktiviert werden|develop#TranslatorExtension]. Für Übersetzungen können Sie auch den Filter [`translate`|filters#translate] verwenden.


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

Übersetzt Werte in andere Sprachen.

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

Dem Übersetzer können auch weitere Parameter übergeben werden:

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


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

Übersetzt Teile des Templates:

```latte
<h1>{translate}Bestellung{/translate}</h1>

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

Das Tag kann auch als [n:Attribut|syntax#n:attributes] geschrieben werden, um den Inhalt des Elements zu übersetzen:

```latte
<h1 n:translate>Bestellung</h1>
```

Latte Tags

Eine Übersicht und Beschreibung aller Latte-Template-System-Tags, die standardmäßig zur Verfügung stehen.

Ausgabe
{$var}, {...} oder {=...} gibt eine escaped Variable oder einen Ausdruck aus
{$var|filter} gibt mit Verwendung von Filtern aus
{l} oder {r} gibt das Zeichen { oder } aus
Bedingungen
{if}{elseif}{else}{/if} if-Bedingung
{ifset}{elseifset}{/ifset} ifset-Bedingung
{ifchanged}{/ifchanged} Test, ob eine Änderung aufgetreten ist
{switch} {case} {default} {/switch} switch-Bedingung
n:else alternativer Inhalt für Bedingungen
Schleifen
{foreach}{/foreach} foreach
{for}{/for} for
{while}{/while} while
{continueIf $cond} mit der nächsten Iteration fortfahren
{skipIf $cond} Iteration überspringen
{breakIf $cond} Schleife abbrechen
{exitIf $cond} vorzeitige Beendigung
{first}{/first} ist es der erste Durchlauf?
{last}{/last} ist es der letzte Durchlauf?
{sep}{/sep} wird noch ein Durchlauf folgen?
{iterateWhile}{/iterateWhile} strukturiertes foreach
$iterator spezielle Variable innerhalb von foreach
Einbindung weiterer Templates
{include 'file.latte'} lädt ein Template aus einer anderen Datei
{sandbox 'file.latte'} lädt ein Template im Sandbox-Modus
Blöcke, Layouts, Template-Vererbung
{block} anonymer Block
{block blockname} definiert einen Block
{define blockname} definiert einen Block zur späteren Verwendung
{include blockname} Darstellung eines Blocks
{include blockname from 'file.latte'} stellt einen Block aus einer Datei dar
{import 'file.latte'} lädt Blöcke aus einem Template
{layout 'file.latte'} / {extends} bestimmt die Layout-Datei
{embed}{/embed} lädt ein Template oder einen Block und ermöglicht das Überschreiben von Blöcken
{ifset blockname}{/ifset} Bedingung, ob ein Block existiert
Ausnahmebehandlung
{try}{else}{/try} Abfangen von Ausnahmen
{rollback} Verwerfen eines try-Blocks
Variablen
{var $foo = value} erstellt eine Variable
{default $foo = value} erstellt eine Variable, wenn sie nicht existiert
{parameters} deklariert Variablen, Typen und Standardwerte
{capture}{/capture} erfasst einen Block in eine Variable
Typen
{varType} deklariert den Typ einer Variable
{varPrint} schlägt Typen für Variablen vor
{templateType} deklariert Variablentypen basierend auf einer Klasse
{templatePrint} schlägt eine Klasse mit Variablentypen vor
Übersetzungen
{_...} gibt eine Übersetzung aus
{translate}{/translate} übersetzt den Inhalt
Sonstiges
{contentType} schaltet das Escaping um und sendet einen HTTP-Header
{debugbreak} platziert einen Breakpoint im Code
{do} führt Code aus, gibt aber nichts aus
{dump} dumpt Variablen in die Tracy Bar
{php} führt beliebigen PHP-Code aus
{spaceless}{/spaceless} entfernt überflüssige Leerzeichen
{syntax} Änderung der Syntax zur Laufzeit
{trace} zeigt den Stack-Trace an
Helfer für HTML-Codierer
n:class dynamische Schreibweise des HTML-Attributs class
n:attr dynamische Schreibweise beliebiger HTML-Attribute
n:tag dynamische Schreibweise des HTML-Element-Namens
n:ifcontent lässt einen leeren HTML-Tag aus
Nur im Nette Framework verfügbar
n:href Link, der in HTML-Elementen <a> verwendet wird
{link} gibt einen Link aus
{plink} gibt einen Link zu einem Presenter aus
{control} rendert eine Komponente
{snippet}{/snippet} ein Snippet, das per AJAX gesendet werden kann
{snippetArea} Wrapper für Snippets
{cache}{/cache} cached einen Teil des Templates
Nur mit Nette Forms verfügbar
{form}{/form} rendert Formular-Tags
{label}{/label} rendert ein Label für ein Formularelement
{input} rendert ein Formularelement
{inputError} gibt eine Fehlermeldung für ein Formularelement aus
n:name aktiviert ein Formularelement
{formContainer}{/formContainer} Zeichnen eines Formular-Containers

Ausgabe

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

In Latte wird das Tag {=...} verwendet, um einen beliebigen Ausdruck auszugeben. Latte legt Wert auf Ihren Komfort, daher ist es nicht nötig, das Gleichheitszeichen zu schreiben, wenn der Ausdruck mit einer Variable oder einem Funktionsaufruf beginnt. Das bedeutet in der Praxis, dass es fast nie notwendig ist, es zu schreiben:

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

Als Ausdruck können Sie alles schreiben, was Sie aus PHP kennen. Sie müssen einfach keine neue Sprache lernen. Zum Beispiel:

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

Bitte suchen Sie in dem vorherigen Beispiel keinen Sinn, aber wenn Sie einen finden sollten, schreiben Sie uns :-)

Ausgabe escapen

Was ist die wichtigste Aufgabe eines Template-Systems? Sicherheitslücken zu verhindern. Und genau das macht Latte immer, wenn Sie etwas ausgeben. Es escaped es automatisch:

<p>{='one < two'}</p>   {* gibt aus: '<p>one &lt; two</p>' *}

Um genau zu sein, verwendet Latte kontextsensitives Escaping, was so wichtig und einzigartig ist, dass wir ihm ein eigenes Kapitel gewidmet haben.

Und was ist, wenn Sie HTML-codierten Inhalt aus einer vertrauenswürdigen Quelle ausgeben? Dann kann das Escaping einfach deaktiviert werden:

{$trustedHtmlString|noescape}

Eine falsche Verwendung des noescape-Filters kann zu einer XSS-Schwachstelle führen! Verwenden Sie ihn niemals, wenn Sie sich nicht absolut sicher sind, was Sie tun, und dass die ausgegebene Zeichenkette aus einer vertrauenswürdigen Quelle stammt.

Ausgabe in JavaScript

Dank des kontextsensitiven Escapings ist es wunderbar einfach, Variablen innerhalb von JavaScript auszugeben, und Latte kümmert sich um das korrekte Escaping.

Die Variable muss nicht unbedingt ein String sein, es wird jeder Datentyp unterstützt, der dann als JSON kodiert wird:

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

Erzeugt:

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

Das ist auch der Grund, warum keine Anführungszeichen um die Variable geschrieben werden: Latte fügt sie bei Strings selbst hinzu. Und wenn Sie eine String-Variable in einen anderen String einfügen möchten, verbinden Sie sie einfach:

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

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

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

Filter

Der ausgegebene Ausdruck kann durch einen Filter modifiziert werden. So können wir zum Beispiel eine Zeichenkette in Großbuchstaben umwandeln und auf maximal 30 Zeichen kürzen:

{$string|upper|truncate:30}

Filter können auch auf Teile eines Ausdrucks auf folgende Weise angewendet werden:

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

Bedingungen

{if} {elseif} {else}

Bedingungen verhalten sich genauso wie ihre Pendants in PHP. Sie können in ihnen die gleichen Ausdrücke verwenden, die Sie aus PHP kennen, Sie müssen keine neue Sprache lernen.

{if $product->inStock > Stock::Minimum}
	Auf Lager
{elseif $product->isOnWay()}
	Unterwegs
{else}
	Nicht verfügbar
{/if}

Wie jedes Paar-Tag kann auch das Paar {if} ... {/if} in Form eines n:Attributs geschrieben werden, zum Beispiel:

<p n:if="$count > 0">{$count} Artikel auf Lager</p>

Wussten Sie, dass Sie n:Attribute mit dem Präfix tag- versehen können? Dann bezieht sich die Bedingung nur auf die Ausgabe der HTML-Tags, und der Inhalt dazwischen wird immer ausgegeben:

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

{* gibt 'Hello' aus, wenn $clickable falsch ist *}
{* gibt '<a href="...">Hello</a>' aus, wenn $clickable wahr ist *}

Göttlich.

n:else

Wenn Sie die Bedingung {if} ... {/if} in Form eines n:Attributs schreiben, haben Sie die Möglichkeit, eine alternative Verzweigung mit n:else anzugeben:

<strong n:if="$count > 0">{$count} Artikel auf Lager</strong>

<em n:else>nicht verfügbar</em>

Das Attribut n:else kann auch in Kombination mit n:ifset, n:foreach, n:try, n:ifcontent und n:ifchanged verwendet werden.

{/if $cond}

Es mag Sie überraschen, dass der Ausdruck in der Bedingung {if} auch im schließenden Tag angegeben werden kann. Dies ist nützlich in Situationen, in denen wir beim Öffnen der Bedingung ihren Wert noch nicht kennen. Nennen wir es eine verzögerte Entscheidung.

Zum Beispiel beginnen wir mit der Ausgabe einer Tabelle mit Datensätzen aus der Datenbank und erst nach Abschluss der Ausgabe stellen wir fest, dass kein Datensatz in der Datenbank vorhanden war. Also setzen wir eine Bedingung in das schließende {/if}-Tag, und wenn kein Datensatz vorhanden ist, wird nichts davon ausgegeben:

{if}
	<h1>Ausgabe von Zeilen aus der Datenbank</h1>

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

Clever, nicht wahr?

In einer verzögerten Bedingung kann auch {else} verwendet werden, aber nicht {elseif}.

{ifset} {elseifset}

Siehe auch {ifset block}

Mit der Bedingung {ifset $var} können wir überprüfen, ob eine Variable (oder mehrere Variablen) existiert und einen nicht-null-Wert hat. Es ist im Grunde dasselbe wie if (isset($var)) in PHP. Wie jedes Paar-Tag kann es auch in Form eines n:Attributs geschrieben werden, also zeigen wir es als Beispiel:

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

{ifchanged}

{ifchanged} überprüft, ob sich der Wert einer Variable seit der letzten Iteration in einer Schleife (foreach, for oder while) geändert hat.

Wenn wir eine oder mehrere Variablen im Tag angeben, wird überprüft, ob sich eine von ihnen geändert hat, und dementsprechend wird der Inhalt ausgegeben. Das folgende Beispiel gibt den ersten Buchstaben des Namens als Überschrift aus, jedes Mal wenn er sich bei der Ausgabe der Namen ändert:

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

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

Wenn wir jedoch kein Argument angeben, wird der gerenderte Inhalt im Vergleich zu seinem vorherigen Zustand überprüft. Das bedeutet, dass wir im vorherigen Beispiel das Argument im Tag weglassen können. Und natürlich können wir auch ein n:Attribut verwenden:

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

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

Innerhalb von {ifchanged} kann auch eine {else}-Klausel verwendet werden.

{switch} {case} {default}

Vergleicht einen Wert mit mehreren Möglichkeiten. Es ist ähnlich wie die bedingte Anweisung switch, die Sie aus PHP kennen. Latte verbessert sie jedoch:

  • es verwendet einen strikten Vergleich (===)
  • es benötigt kein break

Es ist also das genaue Äquivalent zur match-Struktur, die mit PHP 8.0 eingeführt wurde.

{switch $transport}
	{case train}
		Mit dem Zug
	{case plane}
		Mit dem Flugzeug
	{default}
		Anderweitig
{/switch}

Die {case}-Klausel kann mehrere durch Kommas getrennte Werte enthalten:

{switch $status}
{case $status::New}<b>neuer Artikel</b>
{case $status::Sold, $status::Unknown}<i>nicht verfügbar</i>
{/switch}

Schleifen

In Latte finden Sie alle Schleifen, die Sie aus PHP kennen: foreach, for und while.

{foreach}

Wir schreiben die Schleife genauso wie in PHP:

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

Zusätzlich hat sie einige nützliche Funktionen, über die wir jetzt sprechen werden.

Latte überprüft zum Beispiel, ob erstellte Variablen versehentlich globale Variablen mit demselben Namen überschreiben. Das rettet Situationen, in denen Sie davon ausgehen, dass $lang die aktuelle Sprache der Seite ist, und nicht bemerken, dass foreach $langs as $lang diese Variable überschrieben hat.

Die foreach-Schleife kann auch sehr elegant und kompakt als n:Attribut geschrieben werden:

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

Wussten Sie, dass Sie n:Attribute mit dem Präfix inner- versehen können? Dann wird nur der Inhalt des Elements in der Schleife wiederholt:

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

Dies wird also etwas wie folgendes ausgeben:

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

{else}

Innerhalb einer foreach-Schleife kann eine {else}-Klausel angegeben werden, deren Inhalt angezeigt wird, wenn die Schleife leer ist:

<ul>
	{foreach $people as $person}
		<li>{$person->name}</li>
	{else}
		<li><em>Leider sind in dieser Liste keine Benutzer</em></li>
	{/foreach}
</ul>

$iterator

Innerhalb einer foreach-Schleife erstellt Latte eine Variable $iterator, mit der wir nützliche Informationen über die laufende Schleife abrufen können:

  • $iterator->first – ist dies der erste Durchlauf?
  • $iterator->last – ist dies der letzte Durchlauf?
  • $iterator->counter – der wievielte Durchlauf ist es, gezählt ab eins?
  • $iterator->counter0 – der wievielte Durchlauf ist es, gezählt ab null?
  • $iterator->odd – ist dies ein ungerader Durchlauf?
  • $iterator->even – ist dies ein gerader Durchlauf?
  • $iterator->parent – der Iterator, der den aktuellen umgibt
  • $iterator->nextValue – der nächste Eintrag in der Schleife
  • $iterator->nextKey – der Schlüssel des nächsten Eintrags in der Schleife
{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 ist schlau und $iterator->last funktioniert nicht nur bei Arrays, sondern auch wenn die Schleife über einen allgemeinen Iterator läuft, bei dem die Anzahl der Elemente nicht im Voraus bekannt ist.

{first} {last} {sep}

Diese Tags können innerhalb einer {foreach}-Schleife verwendet werden. Der Inhalt von {first} wird gerendert, wenn es sich um den ersten Durchlauf handelt. Der Inhalt von {last} wird gerendert … können Sie es erraten? Ja, wenn es sich um den letzten Durchlauf handelt. Es handelt sich eigentlich um Abkürzungen für {if $iterator->first} und {if $iterator->last}.

Die Tags können auch elegant als n:Attribute verwendet werden:

{foreach $rows as $row}
	{first}<h1>Liste der Namen</h1>{/first}

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

	<hr n:last>
{/foreach}

Der Inhalt des {sep}-Tags wird gerendert, wenn der Durchlauf nicht der letzte ist. Es eignet sich also zum Rendern von Trennzeichen, zum Beispiel Kommas zwischen ausgegebenen Elementen:

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

Das ist ziemlich praktisch, nicht wahr?

{iterateWhile}

Vereinfacht die Gruppierung linearer Daten während der Iteration in einer foreach-Schleife, indem die Iteration in einer verschachtelten Schleife durchgeführt wird, solange eine Bedingung erfüllt ist. Lesen Sie die detaillierte Anleitung.

Es kann auch elegant {first} und {last} im obigen Beispiel ersetzen:

{foreach $rows as $row}
	<table>

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

	</table>
{/foreach}

Siehe auch die Filter batch und group.

{for}

Wir schreiben die Schleife genauso wie in PHP:

{for $i = 0; $i < 10; $i++}
	<span>Element {$i}</span>
{/for}

Das Tag kann auch als n:Attribut verwendet werden:

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

{while}

Wir schreiben die Schleife wieder genauso wie in PHP:

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

Oder als n:Attribut:

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

Eine Variante mit der Bedingung im schließenden Tag ist ebenfalls möglich, die der do-while-Schleife in PHP entspricht:

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

{continueIf} {skipIf} {breakIf}

Zur Steuerung jeder Schleife können die Tags {continueIf ?} und {breakIf ?} verwendet werden, die zum nächsten Element übergehen bzw. die Schleife beenden, wenn eine Bedingung erfüllt ist:

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

Das {skipIf}-Tag ist sehr ähnlich wie {continueIf}, erhöht aber nicht den Zähler $iterator->counter, so dass, wenn wir ihn ausgeben und gleichzeitig einige Elemente überspringen, keine Lücken in der Nummerierung entstehen. Außerdem wird die {else}-Klausel gerendert, wenn wir alle Elemente überspringen.

<ul>
	{foreach $people as $person}
		{skipIf $person->age < 18}
		<li>{$iterator->counter}. {$person->name}</li>
	{else}
		<li><em>Leider gibt es keine Erwachsenen in dieser Liste</em></li>
	{/foreach}
</ul>

{exitIf}

Beendet das Rendern des Templates oder Blocks, wenn eine Bedingung erfüllt ist (sogenannter „early exit“).

{exitIf !$messages}

<h1>Nachrichten</h1>
<div n:foreach="$messages as $message">
   {$message}
</div>

Einbindung von Templates

{include 'file.latte'}

Siehe auch {include block}

Das {include}-Tag lädt und rendert das angegebene Template. Wenn wir in der Sprache unserer Lieblingssprache PHP sprechen würden, wäre es so etwas wie:

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

Eingebundene Templates haben keinen Zugriff auf die Variablen des aktiven Kontexts, sie haben nur Zugriff auf globale Variablen.

Variablen können auf diese Weise an das eingebundene Template übergeben werden:

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

Der Name des Templates kann ein beliebiger PHP-Ausdruck sein:

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

Der eingebundene Inhalt kann mit Filtern modifiziert werden. Das folgende Beispiel entfernt das gesamte HTML und passt die Groß-/Kleinschreibung an:

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

Standardmäßig spielt die Template-Vererbung in diesem Fall keine Rolle. Auch wenn wir in dem eingebundenen Template Blöcke verwenden können, werden die entsprechenden Blöcke in dem Template, in das eingebunden wird, nicht ersetzt. Denken Sie an eingebundene Templates als separate, abgeschirmte Teile von Seiten oder Modulen. Dieses Verhalten kann mit dem Modifikator with blocks geändert werden:

{include 'template.latte' with blocks}

Die Beziehung zwischen dem im Tag angegebenen Dateinamen und der Datei auf der Festplatte ist eine Angelegenheit des Loaders.

{sandbox}

Bei der Einbindung eines vom Endbenutzer erstellten Templates sollten Sie den Sandbox-Modus in Betracht ziehen (weitere Informationen finden Sie in der Sandbox-Dokumentation):

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

{block}

Siehe auch {block name}

Namenlose Blöcke dienen als Möglichkeit, Filter auf einen Teil des Templates anzuwenden. Zum Beispiel kann auf diese Weise der strip-Filter angewendet werden, der überflüssige Leerzeichen entfernt:

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

Ausnahmebehandlung

{try}

Dank dieses Tags ist es extrem einfach, robuste Templates zu erstellen.

Wenn während des Renderns eines {try}-Blocks eine Ausnahme auftritt, wird der gesamte Block verworfen und das Rendering wird danach fortgesetzt:

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

Der Inhalt in der optionalen {else}-Klausel wird nur gerendert, wenn eine Ausnahme auftritt:

{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
	{else}
	<p>Es tut uns leid, die Tweets konnten nicht geladen werden.</p>
{/try}

Das Tag kann auch als n:Attribut verwendet werden:

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

Es ist auch möglich, einen eigenen Handler für Ausnahmen zu definieren, zum Beispiel für Logging-Zwecke.

{rollback}

Ein {try}-Block kann auch manuell mit {rollback} gestoppt und übersprungen werden. Dadurch müssen Sie nicht alle Eingabedaten im Voraus überprüfen und können während des Renderings entscheiden, dass Sie das Objekt überhaupt nicht rendern möchten:

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

Variablen

{var} {default}

Neue Variablen werden im Template mit dem Tag {var} erstellt:

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

{* Mehrfachdeklaration *}
{var $name = 'John Smith', $age = 27}

Das Tag {default} funktioniert ähnlich, mit dem Unterschied, dass es Variablen nur dann erstellt, wenn sie noch nicht existieren. Wenn eine Variable bereits existiert und null enthält, wird sie nicht überschrieben:

{default $lang = 'cs'}

Sie können auch Variablentypen angeben. Diese sind derzeit informativ und werden von Latte nicht überprüft.

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

{parameters}

So wie eine Funktion ihre Parameter deklariert, kann auch ein Template am Anfang seine Variablen deklarieren:

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

Variablen $a und $b ohne angegebenen Standardwert haben automatisch den Standardwert null. Die deklarierten Typen sind derzeit informativ und werden von Latte nicht überprüft.

Andere als die deklarierten Variablen werden nicht in das Template übertragen. Dies unterscheidet es vom Tag {default}.

{capture}

Erfasst die Ausgabe in eine Variable:

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

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

Das Tag kann, wie jedes Paar-Tag, auch als n:Attribut geschrieben werden:

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

Die HTML-Ausgabe wird in der Variable $var als Latte\Runtime\Html-Objekt gespeichert, um unerwünschtes Escaping beim Ausgeben zu verhindern.

Sonstiges

{contentType}

Mit diesem Tag geben Sie an, welchen Inhaltstyp das Template darstellt. Die Optionen sind:

  • html (Standardtyp)
  • xml
  • javascript
  • css
  • calendar (iCal)
  • text

Seine Verwendung ist wichtig, da es das kontextsensitive Escaping festlegt und nur so richtig escapen kann. Zum Beispiel schaltet {contentType xml} in den XML-Modus um, {contentType text} schaltet das Escaping komplett aus.

Wenn der Parameter ein vollständiger MIME-Typ ist, wie zum Beispiel application/xml, wird zusätzlich der HTTP-Header Content-Type an den Browser gesendet:

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

{debugbreak}

Markiert eine Stelle, an der die Programmausführung angehalten und der Debugger gestartet wird, damit der Programmierer die Laufzeitumgebung inspizieren und überprüfen kann, ob das Programm wie erwartet funktioniert. Es unterstützt Xdebug. Eine Bedingung kann hinzugefügt werden, die bestimmt, wann das Programm angehalten werden soll.

{debugbreak}                {* hält das Programm an *}

{debugbreak $counter == 1}  {* hält das Programm an, wenn die Bedingung erfüllt ist *}

{do}

Führt PHP-Code aus und gibt nichts aus. Wie bei allen anderen Tags mit PHP-Code handelt es sich um einen einzelnen Ausdruck, siehe PHP-Einschränkungen.

{do $num++}

{dump}

Gibt eine Variable oder den aktuellen Kontext aus.

{dump $name} {* Gibt die Variable $name aus *}

{dump}       {* Gibt alle aktuell definierten Variablen aus *}

Erfordert die Tracy-Bibliothek.

{php}

Ermöglicht die Ausführung beliebigen PHP-Codes. Das Tag muss durch die RawPhpExtension aktiviert werden.

{spaceless}

Entfernt überflüssige Leerzeichen aus der Ausgabe. Funktioniert ähnlich wie der Filter spaceless.

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

Erzeugt

<ul> <li>Hallo</li> </ul>

Das Tag kann auch als n:Attribut geschrieben werden.

{syntax}

Latte-Tags müssen nicht nur durch einfache geschweifte Klammern begrenzt sein. Wir können auch einen anderen Begrenzer wählen, sogar zur Laufzeit. Dafür wird {syntax …} verwendet, wobei als Parameter angegeben werden kann:

  • double: {{...}}
  • off: schaltet die Verarbeitung von Latte-Tags komplett aus

Mit Hilfe von n:Attributen kann Latte zum Beispiel nur für einen JavaScript-Block ausgeschaltet werden:

<script n:syntax="off">
	var obj = {var: 123}; // dies ist kein Tag mehr
</script>

Latte kann sehr bequem auch innerhalb von JavaScript verwendet werden, man muss nur Konstruktionen wie in diesem Beispiel vermeiden, bei denen direkt nach { ein Buchstabe folgt, siehe Latte innerhalb von JavaScript oder CSS.

Wenn Sie Latte mit {syntax off} ausschalten (d.h. mit einem Tag, nicht mit einem n:Attribut), wird es konsequent alle Tags bis {/syntax} ignorieren.

{trace}

Wirft eine Latte\RuntimeException, deren Stack-Trace im Geiste der Templates ist. Anstelle von Funktions- und Methodenaufrufen enthält er also Blockaufrufe und Template-Einbindungen. Wenn Sie ein Tool zur übersichtlichen Anzeige von geworfenen Ausnahmen verwenden, wie zum Beispiel Tracy, wird Ihnen der Call Stack einschließlich aller übergebenen Argumente übersichtlich angezeigt.

Helfer für HTML-Codierer

n:class

Dank n:class können Sie sehr einfach das HTML-Attribut class genau nach Ihren Vorstellungen generieren.

Beispiel: Ich brauche, dass das aktive Element die Klasse active hat:

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

Und weiter, dass das erste Element die Klassen first und main hat:

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

Und alle Elemente sollen die Klasse list-item haben:

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

Unglaublich einfach, nicht wahr?

n:attr

Das Attribut n:attr kann mit der gleichen Eleganz wie n:class beliebige HTML-Attribute generieren.

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

Abhängig von den zurückgegebenen Werten wird zum Beispiel Folgendes ausgegeben:

<input type="checkbox">

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

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

n:tag

Das Attribut n:tag kann den Namen des HTML-Elements dynamisch ändern.

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

Wenn $heading === null ist, wird der Tag <h1> unverändert ausgegeben. Andernfalls wird der Name des Elements auf den Wert der Variable geändert, so dass für $heading === 'h3' Folgendes ausgegeben wird:

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

Da Latte ein sicheres Template-System ist, überprüft es, ob der neue Tag-Name gültig ist und keine unerwünschten oder schädlichen Werte enthält.

n:ifcontent

Verhindert, dass ein leeres HTML-Element ausgegeben wird, d.h. ein Element, das nichts außer Leerzeichen enthält.

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

Gibt abhängig vom Wert der Variable $error aus:

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

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

Übersetzungen

Damit die Übersetzungs-Tags funktionieren, muss der Übersetzer aktiviert werden. Für Übersetzungen können Sie auch den Filter translate verwenden.

{_...}

Übersetzt Werte in andere Sprachen.

<a href="basket">{_'Warenkorb'}</a>
<span>{_$item}</span>

Dem Übersetzer können auch weitere Parameter übergeben werden:

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

{translate}

Übersetzt Teile des Templates:

<h1>{translate}Bestellung{/translate}</h1>

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

Das Tag kann auch als n:Attribut geschrieben werden, um den Inhalt des Elements zu übersetzen:

<h1 n:translate>Bestellung</h1>