Syntax

Die Syntax von Latte ist aus den praktischen Anforderungen von Webdesignern entstanden. Wir haben die freundlichste Syntax gesucht, mit der sich auch Konstrukte elegant schreiben lassen, die sonst eine echte Herausforderung sind. Zugleich werden alle Ausdrücke genauso geschrieben wie in PHP, Sie müssen also keine neue Sprache lernen. Sie nutzen einfach, was Sie ohnehin schon können.

Unten sehen Sie ein minimales Template, das mehrere grundlegende Elemente zeigt: Tags, n:Attribute, Kommentare und Filter.

{* das ist ein Kommentar *}
<ul n:if=$items>                  {* n:if ist ein n:Attribut *}
{foreach $items as $item}         {* Tag, der eine foreach-Schleife darstellt *}
	<li>{$item|capitalize}</li>   {* Tag, der eine Variable mit einem Filter ausgibt *}
{/foreach}                        {* Ende der Schleife *}
</ul>

Sehen wir uns diese wichtigen Elemente genauer an und wie sie Ihnen helfen, ein großartiges Template zu erstellen.

Tags

Ein Template enthält Tags, die die Logik des Templates steuern (zum Beispiel foreach-Schleifen) oder Ausdrücke ausgeben. Für beides dient ein einziges Trennzeichen { ... }, sodass Sie anders als bei anderen Systemen nicht überlegen müssen, welches Trennzeichen in welcher Situation zu verwenden ist. Folgt auf das Zeichen { unmittelbar ein Leerzeichen, ein Anführungszeichen oder ein weiteres { bzw. }, hält Latte es nicht für den Beginn eines Tags, sodass Sie JavaScript-Konstrukte, JSON oder CSS-Regeln problemlos in Ihren Templates verwenden können.

Siehe die Übersicht aller Tags. Darüber hinaus können Sie eigene Tags erstellen. Sie können auch die Trennzeichen { } ändern oder sie ganz abschalten (mit {syntax double}, {syntax off} oder dem Attribut n:syntax); siehe Ändern der Syntax.

Latte versteht PHP

Innerhalb der Tags können Sie die PHP-Ausdrücke verwenden, die Sie kennen:

Darüber hinaus erweitert Latte die PHP-Syntax um mehrere nette Ergänzungen.

n:Attribute

Jeder Paar-Tag, etwa {if} … {/if}, der auf ein einzelnes HTML-Element wirkt, lässt sich in Form eines n:Attributs schreiben. Das {foreach} aus dem einleitenden Beispiel könnte man zum Beispiel auch so schreiben:

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

Die Funktionalität gilt dann für das HTML-Element, in dem das Attribut steht:

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

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

gibt aus:

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

Mit dem Präfix inner- können wir das Verhalten so ändern, dass es nur für den inneren Teil des Elements gilt:

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

Gibt aus:

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

Oder wir wenden die Funktionalität mit dem Präfix tag- nur auf die HTML-Tags selbst an:

<p><a href={$url} n:tag-if="$url">Titel</a></p>

Was je nach Variable $url ausgibt:

{* wenn $url leer ist *}
<p>Titel</p>

{* wenn $url 'https://nette.org' enthält *}
<p><a href="https://nette.org">Titel</a></p>

n:Attribute sind jedoch nicht nur eine Abkürzung für Paar-Tags, es gibt auch einige reine n:Attribute, zum Beispiel den besten Freund des Coders n:class oder das sehr praktische n:href.

Neben der Schreibweise mit Anführungszeichen <div n:if="$foo"> können Sie die alternative Schreibweise mit geschweiften Klammern <div n:if={$foo}> verwenden. Der wesentliche Vorteil ist, dass Sie innerhalb von {...} sowohl einfache als auch doppelte Anführungszeichen frei verwenden können:

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

Smarte HTML-Attribute

Latte macht die Arbeit mit gewöhnlichen HTML-Attributen ausgesprochen leicht. Es kümmert sich für Sie um boolesche Attribute wie checked, entfernt Attribute, die null enthalten, und erlaubt es, die Werte von class und style mit Arrays zusammenzusetzen. Für data--Attribute serialisiert es Daten sogar automatisch nach JSON.

{* null entfernt das Attribut *}
<div title={$title}>

{* boolescher Wert steuert die Anwesenheit boolescher Attribute *}
<input type="checkbox" checked={$isChecked}>

{* Arrays funktionieren in class *}
<div class={['btn', 'btn-primary', active => $isActive]}>

{* Arrays werden in data--Attributen nach JSON kodiert *}
<div data-config={[theme: dark, version: 2]}>

Mehr dazu im eigenen Kapitel Smarte HTML-Attribute.

Filter

Siehe die Übersicht der Standardfilter.

Filter werden nach dem Pipe-Symbol geschrieben (ein Leerzeichen davor ist erlaubt):

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

Filter lassen sich verketten und werden der Reihe nach von links nach rechts angewendet:

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

Die Argumente folgen dem Namen des Filters nach einem Doppelpunkt, weitere werden durch Kommas getrennt; ein Aufruf mit Klammern funktioniert ebenfalls:

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

Filter lassen sich auch auf einen Ausdruck anwenden:

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

Auf einen Block:

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

Oder direkt auf einen Wert (in Verbindung mit dem Tag {=expr}):

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

Kann der Wert null sein und wollen Sie den Filter in diesem Fall nicht anwenden, verwenden Sie den Nullsafe-Filter ?|:

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

Dynamische HTML-Tags

Latte unterstützt dynamische HTML-Tags, die nützlich sind, wenn Sie beim Namen des Tags Flexibilität brauchen:

<h{$level}>Überschrift</h{$level}>

Der obige Code kann zum Beispiel je nach Wert der Variablen $level <h1>Überschrift</h1> oder <h2>Überschrift</h2> erzeugen. Dynamische HTML-Tags müssen in Latte immer paarig sein. Ihre Alternative ist n:tag.

Weil Latte ein sicheres Templating-System ist, prüft es, dass der entstehende Tag-Name gültig ist und keine unerwünschten oder schädlichen Werte enthält. Es sorgt außerdem dafür, dass der Name des schließenden Tags immer dem des öffnenden entspricht.

Kommentare

Kommentare werden so geschrieben und gelangen nicht in die Ausgabe:

{* das ist ein Kommentar in Latte *}

Innerhalb von Tags funktionieren PHP-Kommentare:

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

Umgang mit Leerraum

Latte geht mit Leerraum intelligent um. Sie können Ihren Code zur besseren Lesbarkeit frei einrücken, und die Ausgabe bleibt sauber. Steht ein Steuer-Tag allein auf einer Zeile, wird die gesamte Zeile (Einrückung und Zeilenumbruch) aus der Ausgabe entfernt (das gilt nicht für Tags, die etwas ausgeben, etwa {$var}, {=...} oder {_...}, die ihre Einrückung und den abschließenden Zeilenumbruch behalten):

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

Gibt aus:

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

Was aber, wenn ein Tag nicht allein auf einer Zeile steht, sondern neben anderem Inhalt? Der Leerraum vor dem Tag gehört dann in den Tag:

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

Die Einrückung liegt faktisch innerhalb von {if}: Ist $foo falsch, wird nichts ausgegeben – nicht einmal die Einrückung oder eine leere Zeile. Ist $foo wahr, enthält die Ausgabe die Einrückung ganz natürlich. Sie schreiben also einfach gut strukturierte Templates und die Ausgabe ist stets sauber.

Für eine noch sauberere Ausgabe können Sie die Funktion Dedent aktivieren, die zusätzlich die Einrückung entfernt, die durch die Verschachtelung in Paar-Tags wie {if} oder {foreach} entsteht.

Syntaktischer Zucker

Strings ohne Anführungszeichen

Bei einfachen Strings lassen sich die Anführungszeichen weglassen:

wie in PHP:  {var $arr = ['hello', 'btn--default', '€']}

verkürzt:    {var $arr = [hello, btn--default, €]}

Einfache Strings sind solche, die ausschließlich aus Buchstaben, Ziffern, Unterstrichen, Bindestrichen und Punkten bestehen. Sie dürfen nicht mit einer Ziffer beginnen und weder mit einem Bindestrich beginnen noch enden. Sie dürfen nicht ausschließlich aus Großbuchstaben und Unterstrichen bestehen, denn dann gelten sie als Konstanten (z. B. PHP_VERSION). Und sie dürfen nicht mit den Schlüsselwörtern kollidieren: and, array, clone, default, false, in, instanceof, new, null, or, return, true, xor.

Konstanten

Verwenden Sie den Trenner des globalen Namespace, um globale Konstanten von einfachen Strings zu unterscheiden:

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

Diese Schreibweise ist in PHP selbst vollkommen gültig, wo der Backslash anzeigt, dass die Konstante im globalen Namespace liegt.

Kurzer ternärer Operator

Ist der dritte Wert des ternären Operators leer, lässt er sich weglassen:

wie in PHP:  {$stock ? 'Auf Lager' : ''}

verkürzt:    {$stock ? 'Auf Lager'}

Moderne Schreibweise der Schlüssel in Arrays

Die Schlüssel von Arrays lassen sich ähnlich schreiben wie benannte Parameter beim Aufruf von Funktionen:

wie in PHP:  {var $arr = ['one' => 'item 1', 'two' => 'item 2']}

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

Filter

Filter lassen sich auf jeden beliebigen Ausdruck anwenden; setzen Sie den gesamten Ausdruck einfach in Klammern:

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

Operator in

Der Operator in kann die Funktion in_array() ersetzen. Der Vergleich ist immer strikt:

{* wie in_array($item, $items, true) *}
{if $item in $items}
	...
{/if}

Ein Fenster in die Geschichte

Im Laufe seiner Geschichte führte Latte mehrere Formen von syntaktischem Zucker ein, die einige Jahre später in PHP selbst auftauchten. In Latte ließen sich zum Beispiel Arrays als [1, 2, 3] statt array(1, 2, 3) schreiben oder der Nullsafe-Operator $obj?->foo verwenden, lange bevor das in PHP selbst möglich war. Latte führte auch den Operator zum Entpacken von Arrays (expand) $arr ein, der dem heutigen Operator ...$arr aus PHP entspricht.

Einschränkungen von PHP in Latte

In Latte lassen sich nur PHP-Ausdrücke schreiben. Anweisungen, die mit einem Semikolon enden, lassen sich also nicht verwenden. Sie können keine Klassen deklarieren und keine Kontrollstrukturen wie if, foreach, switch, return, try, throw und weitere verwenden, für die Latte seine Tags bietet. Ebenso wenig lassen sich Attribute, Backticks oder manche magischen Konstanten verwenden. Auch unset, echo, include, require, exit und eval lassen sich nicht verwenden, denn sie sind keine Funktionen, sondern besondere Sprachkonstrukte von PHP und damit keine Ausdrücke. Unterstützt werden nur mehrzeilige Kommentare /* ... */.

Diese Einschränkungen lassen sich jedoch umgehen, indem Sie die Extension RawPhpExtension aktivieren, die es erlaubt, im Tag {php ...} beliebigen PHP-Code auf Verantwortung des Template-Autors zu verwenden.

Version: 3.x