Syntaxe
La syntaxe de Latte est née des besoins pratiques des webdesigners. Nous cherchions la syntaxe la plus accueillante possible, celle qui permet d'écrire élégamment des constructions qui relèvent autrement du casse-tête. En même temps, toutes les expressions s'écrivent exactement comme en PHP, si bien que vous n'avez pas de nouveau langage à apprendre. Vous mettez simplement à profit ce que vous savez déjà.
Ci-dessous se trouve un template minimal qui illustre plusieurs éléments de base : balises, n:attributs, commentaires et filtres.
{* ceci est un commentaire *}
<ul n:if=$items> {* n:if est un n:attribut *}
{foreach $items as $item} {* balise représentant une boucle foreach *}
<li>{$item|capitalize}</li> {* balise affichant une variable avec un filtre *}
{/foreach} {* fin de la boucle *}
</ul>
Examinons de plus près ces éléments importants et la façon dont ils vous aident à créer un template épatant.
Balises
Un template contient des balises qui pilotent sa logique (par exemple les boucles foreach) ou affichent des expressions.
Un unique délimiteur { ... } sert aux deux, si bien que vous n'avez pas à vous demander lequel employer dans quelle
situation, contrairement à d'autres systèmes. Si le caractère { est immédiatement suivi d'un espace, d'un
guillemet ou d'un autre { ou }, Latte n'y voit pas le début d'une balise, ce qui vous permet d'utiliser
sans souci des constructions JavaScript, du JSON ou des règles CSS dans vos templates.
Consultez l'aperçu de toutes les balises. Vous pouvez en outre créer vos
propres balises personnalisées. Vous pouvez aussi changer les délimiteurs
{ } ou les désactiver complètement (avec {syntax double}, {syntax off} ou l'attribut
n:syntax) ; voyez changement de syntaxe.
Latte comprend PHP
À l'intérieur des balises, vous pouvez utiliser les expressions PHP qui vous sont familières :
- les variables
- les chaînes (y compris HEREDOC et NOWDOC), les tableaux, les nombres, etc.
- les opérateurs
- les appels de fonctions et de méthodes (que le sandbox peut restreindre)
- match
- les fonctions fléchées
- la syntaxe first class callable
- les commentaires multilignes
/* ... */ - etc.
Latte enrichit par ailleurs la syntaxe de PHP de quelques extensions plaisantes.
n:attributs
Toute balise paire, comme {if} … {/if}, qui agit sur un seul élément HTML peut se réécrire sous forme de
n:attribut. Le {foreach} de l'exemple d'introduction pourrait ainsi s'écrire :
<ul n:if=$items>
<li n:foreach="$items as $item">{$item|capitalize}</li>
</ul>
La fonctionnalité s'applique alors à l'élément HTML dans lequel elle est placée :
{var $items = ['I', '♥', 'Latte']}
<p n:foreach="$items as $item">{$item}</p>
affiche :
<p>I</p>
<p>♥</p>
<p>Latte</p>
Grâce au préfixe inner-, nous pouvons modifier ce comportement pour qu'il ne s'applique qu'à l'intérieur de
l'élément :
<div n:inner-foreach="$items as $item">
<p>{$item}</p>
<hr>
</div>
Affiche :
<div>
<p>I</p>
<hr>
<p>♥</p>
<hr>
<p>Latte</p>
<hr>
</div>
Ou bien, avec le préfixe tag-, nous n'appliquons la fonctionnalité qu'aux balises HTML elles-mêmes :
<p><a href={$url} n:tag-if="$url">Title</a></p>
Ce qui affiche, selon la variable $url :
{* quand $url est vide *}
<p>Title</p>
{* quand $url contient 'https://nette.org' *}
<p><a href="https://nette.org">Title</a></p>
Les n:attributs ne sont toutefois pas qu'un raccourci pour les balises paires : il en existe aussi de purs, par exemple le meilleur ami du codeur n:class ou le très pratique n:href.
Outre la syntaxe avec guillemets <div n:if="$foo">, vous pouvez employer la syntaxe alternative à accolades
<div n:if={$foo}>. Son principal avantage est de vous laisser utiliser librement guillemets simples et doubles
à l'intérieur de {...} :
<div n:if={str_contains($val, "foo")}> ... </div>
Attributs HTML intelligents
Latte rend le travail avec les attributs HTML standard incroyablement simple. Il gère pour vous les attributs booléens comme
checked, supprime les attributs valant null et vous laisse composer les valeurs de class et
style à l'aide de tableaux. Il sérialise même automatiquement en JSON les données des attributs
data-.
{* null supprime l'attribut *}
<div title={$title}>
{* un booléen pilote la présence des attributs booléens *}
<input type="checkbox" checked={$isChecked}>
{* les tableaux fonctionnent dans class *}
<div class={['btn', 'btn-primary', active => $isActive]}>
{* les tableaux sont encodés en JSON dans les attributs data- *}
<div data-config={[theme: dark, version: 2]}>
Pour en savoir plus, voyez le chapitre dédié Attributs HTML intelligents.
Filtres
Consultez l'aperçu des filtres standard.
Les filtres s'écrivent après la barre verticale (un espace peut la précéder) :
<h1>{$heading|upper}</h1>
Les filtres peuvent s'enchaîner et s'appliquent alors de gauche à droite :
<h1>{$heading|lower|capitalize}</h1>
Les arguments suivent le nom du filtre après un deux-points, les suivants étant séparés par des virgules ; un appel entre parenthèses fonctionne également :
<h1>{$heading|truncate:20,''}</h1>
<h1>{$heading|truncate(20, '')}</h1>
Les filtres peuvent aussi s'appliquer à une expression :
{var $name = ($title|upper) . ($subtitle|lower)}
À un bloc :
<h1>{block |lower}{$heading}{/block}</h1>
Ou directement à une valeur (en combinaison avec la balise {=expr}) :
<h1>{=' Hello world '|trim}</h1>
Si la valeur peut être null et que vous voulez éviter d'appliquer le filtre dans ce cas, utilisez le filtre nullsafe ?| :
<h1>{$heading?|upper}</h1>
Balises HTML dynamiques
Latte prend en charge les balises HTML dynamiques, utiles quand vous avez besoin de souplesse dans les noms de balises :
<h{$level}>Heading</h{$level}>
Le code ci-dessus peut par exemple générer <h1>Heading</h1> ou
<h2>Heading</h2> selon la valeur de la variable $level. Les balises HTML dynamiques doivent
toujours être paires dans Latte. Leur alternative est n:tag.
Parce que Latte est un système de templates sûr, il vérifie que le nom de balise obtenu est valide et ne contient aucune valeur indésirable ou malveillante. Il garantit aussi que le nom de la balise fermante correspond toujours à celui de la balise ouvrante.
Commentaires
Les commentaires s'écrivent ainsi et n'apparaissent pas dans la sortie :
{* ceci est un commentaire en Latte *}
Les commentaires PHP fonctionnent à l'intérieur des balises :
{include 'file.info', /* value: 123 */}
Gestion des espaces
Latte traite les espaces intelligemment. Vous pouvez indenter votre code librement pour le rendre lisible, la sortie reste
propre. Quand une balise de contrôle est seule sur une ligne, toute la ligne (indentation et saut de ligne) disparaît de la
sortie (cela ne vaut pas pour les balises qui affichent quelque chose, comme {$var}, {=...} ou
{_...}, qui conservent leur indentation et leur saut de ligne final) :
<ul>
{foreach $items as $item}
<li>{$item}</li>
{/foreach}
</ul>
Affiche :
<ul>
<li>foo</li>
<li>bar</li>
</ul>
Et si une balise n'est pas seule sur sa ligne, mais côtoie d'autres contenus ? L'espace qui précède la balise appartient alors à l'intérieur de la balise :
<div>
{if $foo}hello{/if}
</div>
L'indentation se retrouve de fait à l'intérieur du {if} : quand $foo est faux, rien n'est affiché,
pas même l'indentation ou une ligne vide. Quand $foo est vrai, la sortie contient naturellement l'indentation. Vous
écrivez simplement des templates bien structurés et la sortie reste toujours propre.
Pour une sortie encore plus nette, vous pouvez activer la fonctionnalité Dedent, qui supprime en plus l'indentation due à l'imbrication dans des
balises paires comme {if} ou {foreach}.
Sucre syntaxique
Chaînes sans guillemets
Les guillemets peuvent être omis pour les chaînes simples :
comme en PHP : {var $arr = ['hello', 'btn--default', '€']}
en abrégé : {var $arr = [hello, btn--default, €]}
Les chaînes simples sont celles composées uniquement de lettres, de chiffres, de tirets bas, de traits d'union et de points.
Elles ne doivent pas commencer par un chiffre ni commencer ou finir par un trait d'union. Elles ne doivent pas être composées
uniquement de majuscules et de tirets bas, car elles seraient alors prises pour des constantes (par ex. PHP_VERSION).
Et elles ne doivent pas entrer en conflit avec les mots-clés : and, array, clone,
default, false, in, instanceof, new, null,
or, return, true, xor.
Constantes
Utilisez le séparateur d'espace de noms global pour distinguer les constantes globales des chaînes simples :
{if \PROJECT_ID === 1} ... {/if}
Cette notation est parfaitement valide en PHP lui-même, où la barre oblique inverse indique que la constante se trouve dans l'espace de noms global.
Opérateur ternaire abrégé
Si la troisième valeur de l'opérateur ternaire est vide, elle peut être omise :
comme en PHP : {$stock ? 'En stock' : ''}
en abrégé : {$stock ? 'En stock'}
Notation moderne des clés dans un tableau
Les clés d'un tableau peuvent s'écrire comme les paramètres nommés lors d'un appel de fonction :
comme en PHP : {var $arr = ['one' => 'item 1', 'two' => 'item 2']}
en moderne : {var $arr = [one: 'item 1', two: 'item 2']}
Filtres
Les filtres peuvent s'appliquer à n'importe quelle expression ; il suffit d'entourer l'expression entière de parenthèses :
{var $content = ($text|truncate: 30|upper)}
Opérateur in
L'opérateur in peut remplacer la fonction in_array(). La comparaison est toujours stricte :
{* comme in_array($item, $items, true) *}
{if $item in $items}
...
{/if}
Une fenêtre sur l'histoire
Au fil de son histoire, Latte a introduit plusieurs éléments de sucre syntaxique apparus dans PHP lui-même quelques années
plus tard. Dans Latte, on pouvait par exemple écrire les tableaux [1, 2, 3] au lieu de array(1, 2, 3),
ou utiliser l'opérateur nullsafe $obj?->foo bien avant que PHP ne le permette. Latte a aussi introduit
l'opérateur de développement de tableau (expand) $arr, équivalent de l'actuel opérateur ...$arr
de PHP.
Limitations de PHP dans Latte
Seules des expressions PHP peuvent s'écrire dans Latte. Autrement dit, les instructions terminées par un point-virgule sont
exclues. Vous ne pouvez pas déclarer de classes ni utiliser les structures de contrôle telles que if,
foreach, switch, return, try, throw et consorts, pour lesquelles
Latte propose ses balises. Vous ne pouvez pas non plus utiliser les attributs, les accents graves ou certaines constantes magiques. Vous ne pouvez pas davantage employer
unset, echo, include, require, exit, eval, car ce ne
sont pas des fonctions mais des constructions particulières du langage PHP, et donc pas des expressions. Seuls les commentaires
multilignes /* ... */ sont pris en charge.
Ces limitations peuvent toutefois être contournées en activant l'extension RawPhpExtension, qui vous permet d'utiliser n'importe quel code
PHP dans la balise {php ...}, sous la responsabilité de l'auteur du template.