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:
- Variablen
- Strings (einschließlich HEREDOC und NOWDOC), Arrays, Zahlen usw.
- Operatoren
- Aufrufe von Funktionen und Methoden (die sich per Sandbox einschränken lassen)
- match
- Arrow-Funktionen
- First-Class-Callable-Syntax
- mehrzeilige Kommentare
/* ... */ - usw.
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.