Nette Documentation Preview

syntax
Latte Marqueurs
***************

.[perex]
Résumé et description de toutes les balises intégrées de Latte.

.[table-latte-tags language-latte]
|## Impression
| `{$var}`, `{...}` ou `{=...}` | [imprime une variable ou une expression échappée |#printing]
| `{$var\|filter}` | [imprime avec des filtres |#filters]
| `{l}` ou `{r}` | imprime le caractère `{` or `}`

.[table-latte-tags language-latte]
|## Conditions
| `{if}`... `{elseif}`... `{else}`... `{/if}` | [condition if |#if-elseif-else]
| `{ifset}`... `{elseifset}`... `{/ifset}` | [condition ifset |#ifset-elseifset]
| `{ifchanged}`... `{/ifchanged}` | [test si un changement est intervenu|#ifchanged]
| `{switch}` `{case}` `{default}` `{/switch}` | [condition switch |#switch-case-default]
| `n:else` | [contenu alternatif pour les conditions |#n:else]

.[table-latte-tags language-latte]
|## Boucles
| `{foreach}`... `{/foreach}` | [foreach |#foreach]
| `{for}`... `{/for}` | [for |#for]
| `{while}`... `{/while}` | [while |#while]
| `{continueIf $cond}` | [continuer à l'itération suivante |#continueif-skipif-breakif]
| `{skipIf $cond}` | [sauter l'itération de la boucle actuelle |#continueif-skipif-breakif]
| `{breakIf $cond}` | [interrompt la boucle |#continueif-skipif-breakif]
| `{exitIf $cond}` | [sortie anticipée |#exitif]
| `{first}`... `{/first}` | [est-ce la première itération ? |#first-last-sep]
| `{last}`... `{/last}` | [est-ce la dernière itération ? |#first-last-sep]
| `{sep}`... `{/sep}` | [la prochaine itération suivra-t-elle ? |#first-last-sep]
| `{iterateWhile}`... `{/iterateWhile}` | [foreach structuré |#iterateWhile]
| `$iterator` | [variable spéciale dans la boucle foreach |#$iterator]

.[table-latte-tags language-latte]
|## Inclure d'autres modèles
| `{include 'file.latte'}` | [inclut un modèle d'un autre fichier |#include]
| `{sandbox 'file.latte'}` | [inclut un modèle en mode sandbox |#sandbox]

.[table-latte-tags language-latte]
|## Blocs, mises en page, héritage de modèles
| `{block}` | [bloc anonyme |#block]
| `{block blockname}` | [définition du bloc |template-inheritance#blocks]
| `{define blockname}` | [Définition du bloc pour une utilisation future |template-inheritance#definitions]
| `{include blockname}` | [Imprime le bloc |template-inheritance#printing-blocks]
| `{include blockname from 'file.latte'}` | [Imprime un bloc depuis un fichier |template-inheritance#printing-blocks]
| `{import 'file.latte'}` | [charge des blocs à partir d'un autre modèle |template-inheritance#horizontal-reuse]
| `{layout 'file.latte'}` / `{extends}` | [spécifie un fichier de mise en page |template-inheritance#layout-inheritance]
| `{embed}`... `{/embed}` | [charge le modèle ou le bloc et vous permet d'écraser les blocs |template-inheritance#unit-inheritance]
| `{ifset blockname}`... `{/ifset}` | [conditionne la définition d'un bloc |template-inheritance#checking-block-existence]

.[table-latte-tags language-latte]
|## Traitement des exceptions
| `{try}`... `{else}`... `{/try}` | [attrape les exceptions |#try]
| `{rollback}` | [rejeter le bloc d'essai |#rollback]

.[table-latte-tags language-latte]
|## Variables
| `{var $foo = value}` | [création de variables |#var-default]
| `{default $foo = value}` | [valeur par défaut quand la variable n'est pas déclarée |#var-default]
| `{parameters}` | [déclare des variables, des types et des valeurs par défaut |#parameters]
| `{capture}`... `{/capture}` | [capture une section à une variable |#capture]

.[table-latte-tags language-latte]
|## Types
| `{varType}` | [déclare le type de la variable |type-system#varType]
| `{varPrint}` | [suggère des types de variables |type-system#varPrint]
| `{templateType}` | [déclare les types de variables en utilisant une classe |type-system#templateType]
| `{templatePrint}` | [génère une classe avec des propriétés |type-system#templatePrint]

.[table-latte-tags language-latte]
|## Traduction
| `{_string}` | [imprime la traduction |#Translation]
| `{translate}`... `{/translate}` | [traduit le contenu |#Translation]

.[table-latte-tags language-latte]
|## Autres
| `{contentType}` | [change le mode d'échappement et envoie l'en-tête HTTP |#contenttype]
| `{debugbreak}` | [met un point d'arrêt au code |#debugbreak]
| `{do}` | [évalue une expression sans l'imprimer |#do]
| `{dump}` | [Décharge les variables dans la barre de Tracy |#dump]
| `{php}` | [exécute n'importe quel code PHP |#php]
| `{spaceless}`... `{/spaceless}` | [supprime les espaces blancs inutiles |#spaceless]
| `{syntax}` | [change la syntaxe au moment de l'exécution |#syntax]
| `{trace}` | [montre la trace de la pile |#trace]

.[table-latte-tags language-latte]
|## Aides pour les balises HTML
| `n:class` | [Attribut de classe intelligent |#n:class]
| `n:attr` | [attributs HTML intelligents |#n:attr]
| `n:tag` | [Nom dynamique de l'élément HTML |#n:tag]
| `n:ifcontent` | [Omettre une balise HTML vide |#n:ifcontent]

.[table-latte-tags language-latte]
|## Disponible uniquement dans Nette Framework
| `n:href` | [lien dans les éléments HTML `<a>`  |application:creating-links#In the Presenter Template]
| `{link}` | [imprime un lien |application:creating-links#In the Presenter Template]
| `{plink}` | [imprime un lien vers un présentateur |application:creating-links#In the Presenter Template]
| `{control}` | [imprime un composant |application:components#Rendering]
| `{snippet}`... `{/snippet}` | [un snippet de modèle qui peut être envoyé par AJAX |application:ajax#snippets-in-latte]
| `{snippetArea}` | [enveloppe des snippets |application:ajax#snippet-areas]
| `{cache}`... `{/cache}` | [met en cache une section de modèle |caching:#caching-in-latte]

.[table-latte-tags language-latte]
|## Disponible uniquement avec Nette Forms
| `{form}`... `{/form}` | [imprime un élément de formulaire |forms:rendering#form]
| `{label}`... `{/label}` | [imprime une étiquette d'entrée de formulaire |forms:rendering#label-input]
| `{input}` | [imprime un élément de saisie de formulaire |forms:rendering#label-input]
| `{inputError}` | [imprime un message d'erreur pour l'élément de saisie du formulaire |forms:rendering#inputError]
| `n:name` | [active un élément de saisie HTML |forms:rendering#n:name]
| `{formContainer}`... `{/formContainer}` | [rendre le conteneur de formulaire |forms:rendering#special-cases]


Impression de .[#toc-printing]
==============================


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

Latte utilise la balise `{=...}` pour imprimer n'importe quelle expression sur la sortie. Si l'expression commence par une variable ou un appel de fonction, il n'est pas nécessaire d'écrire un signe égal. Ce qui, en pratique, signifie qu'il n'est presque jamais nécessaire de l'écrire :

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

Vous pouvez écrire tout ce que vous connaissez de PHP sous forme d'expression. Vous n'avez simplement pas besoin d'apprendre un nouveau langage. Par exemple :


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

Ne cherchez pas de sens dans l'exemple précédent, mais si vous en trouvez un, écrivez-nous :-)


Sortie d'échappement .[#toc-escaping-output]
--------------------------------------------

Quelle est la tâche la plus importante d'un système de modèles ? Éviter les failles de sécurité. Et c'est exactement ce que fait Latte lorsque vous imprimez quelque chose en sortie. Il échappe automatiquement tout :

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

Pour être précis, Latte utilise l'échappement contextuel, qui est une fonctionnalité tellement importante et unique que nous lui avons consacré [un chapitre séparé|safety-first#context-aware-escaping].

Et si vous imprimez du contenu codé en HTML à partir d'une source fiable ? Vous pouvez alors facilement désactiver l'échappement :

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

.[warning]
Une mauvaise utilisation du filtre `noescape` peut conduire à une vulnérabilité XSS ! Ne l'utilisez jamais sans être **absolument sûr** de ce que vous faites et que la chaîne que vous imprimez provient d'une source fiable.


Impression en JavaScript .[#toc-printing-in-javascript]
-------------------------------------------------------

Grâce à l'échappement contextuel, il est merveilleusement facile d'imprimer des variables en JavaScript, et Latte les échappera correctement.

La variable ne doit pas nécessairement être une chaîne de caractères, n'importe quel type de données est pris en charge, qui est ensuite encodé en JSON :

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

Génère :

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

C'est aussi la raison pour laquelle **ne pas mettre les variables entre guillemets** : Latte les ajoute autour des chaînes de caractères. Et si vous voulez mettre une variable de chaîne dans une autre chaîne, il suffit de les concaténer :

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

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

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


Filtres .[#toc-filters]
-----------------------

L'expression imprimée peut être modifiée [par des filtres |syntax#filters]. Par exemple, cet exemple convertit la chaîne en majuscules et la raccourcit à un maximum de 30 caractères :

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

Vous pouvez également appliquer des filtres à des parties d'une expression comme suit :

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


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


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

Les conditions se comportent de la même manière que leurs équivalents en PHP. Vous pouvez utiliser les mêmes expressions que celles que vous connaissez en PHP, vous n'avez pas besoin d'apprendre un nouveau langage.

```latte
{if $product->inStock > Stock::Minimum}
	In stock
{elseif $product->isOnWay()}
	On the way
{else}
	Not available
{/if}
```

Comme toute balise de paire, une paire de `{if} ... {/ if}` peut être écrite comme [n:attribut |syntax#n:attributes], par exemple :

```latte
<p n:if="$count > 0">In stock {$count} items</p>
```

Savez-vous que vous pouvez ajouter le préfixe `tag-` aux n:attributs ? La condition n'affectera alors que les balises HTML et le contenu situé entre elles sera toujours imprimé :

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

{* prints 'Hello' when $clickable is falsey *}
{* prints '<a href="...">Hello</a>' when $clickable is truthy *}
```

Bien.


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

Si vous écrivez la condition `{if} ... {/if}` sous la forme d'un [n:attribut |syntax#n:attributes], vous avez la possibilité de spécifier une branche alternative en utilisant `n:else`:

```latte
<strong n:if="$count > 0">In stock {$count} items</strong>

<em n:else>not available</em>
```

L'attribut `n:else` peut également être utilisé en conjonction avec [`n:ifset` |#ifset-elseifset], [`n:foreach` |#foreach], [`n:try` |#try], [`n:ifcontent` |#n:ifcontent], et [`n:ifchanged` |#ifchanged].


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

Vous serez peut-être surpris de constater que l'expression de la condition `{if}` peut également être spécifiée dans la balise de fin. Cela est utile dans les situations où nous ne connaissons pas encore la valeur de la condition à l'ouverture de la balise. Appelons cela une décision différée.

Par exemple, nous commençons à lister un tableau avec des enregistrements de la base de données, et ce n'est qu'après avoir terminé le rapport que nous nous rendons compte qu'il n'y avait aucun enregistrement dans la base de données. Nous mettons donc une condition dans la balise de fin `{/if}` et s'il n'y a pas d'enregistrement, rien ne sera imprimé :

```latte
{if}
	<h1>Printing rows from the database</h1>

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

Pratique, n'est-ce pas ?

Vous pouvez également utiliser `{else}` dans la condition différée, mais pas `{elseif}`.


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

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

Utilisez la condition `{ifset $var}` pour déterminer si une variable (ou plusieurs variables) existe et a une valeur non nulle. C'est en fait la même chose que `if (isset($var))` en PHP. Comme toute balise de paire, elle peut être écrite sous la forme [n:attribut |syntax#n:attributes], alors montrons-la en exemple :

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


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

`{ifchanged}` vérifie si la valeur d'une variable a changé depuis la dernière itération de la boucle (foreach, for, ou while).

Si nous spécifions une ou plusieurs variables dans la balise, elle vérifiera si l'une d'entre elles a changé et imprimera le contenu en conséquence. Par exemple, l'exemple suivant imprime la première lettre d'un nom en tant qu'en-tête chaque fois qu'elle change lors de l'énumération des noms :

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

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

Toutefois, si aucun argument n'est fourni, le contenu rendu lui-même sera vérifié par rapport à son état précédent. Cela signifie que dans l'exemple précédent, nous pouvons omettre sans risque l'argument dans la balise. Et bien sûr, nous pouvons également utiliser [n:attribute |syntax#n:attributes]:

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

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

Vous pouvez également inclure une clause `{else}` à l'intérieur de `{ifchanged}`.


`{switch}` `{case}` `{default}`
-------------------------------
Compare la valeur avec plusieurs options. Cette structure est similaire à la structure `switch` que vous connaissez de PHP. Cependant, Latte l'améliore :

- utilise une comparaison stricte (`===`)
- n'a pas besoin d'un `break`

C'est donc l'équivalent exact de la structure `match` fournie par PHP 8.0.

```latte
{switch $transport}
	{case train}
		By train
	{case plane}
		By plane
	{default}
		Differently
{/switch}
```

La clause `{case}` peut contenir plusieurs valeurs séparées par des virgules :

```latte
{switch $status}
{case $status::New}<b>new item</b>
{case $status::Sold, $status::Unknown}<i>not available</i>
{/switch}
```


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

Dans Latte, toutes les boucles que vous connaissez de PHP sont à votre disposition : foreach, for et while.


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

Vous écrivez le cycle exactement de la même manière qu'en PHP :

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

En outre, il a quelques tweaks pratiques dont nous allons parler maintenant.

Par exemple, Latte vérifie que les variables créées n'écrasent pas accidentellement les variables globales du même nom. Cela vous sauvera lorsque vous supposerez que `$lang` est la langue actuelle de la page, et que vous ne réaliserez pas que `foreach $langs as $lang` a écrasé cette variable.

La boucle foreach peut également être écrite de manière très élégante et économique avec [n:attribute |syntax#n:attributes]:

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

Saviez-vous que vous pouvez ajouter le préfixe `inner-` au préfixe n:attribute ? Ainsi, seule la partie intérieure de l'élément sera répétée dans la boucle :

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

Donc ça imprime quelque chose comme :

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


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

La boucle `foreach` peut prendre une clause optionnelle `{else}` dont le texte est affiché si le tableau donné est vide :

```latte
<ul>
	{foreach $people as $person}
		<li>{$person->name}</li>
	{else}
		<li><em>Sorry, no users in this list</em></li>
	{/foreach}
</ul>
```


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

À l'intérieur de la boucle `foreach`, la variable `$iterator` est initialisée. Elle contient des informations importantes sur la boucle en cours.

- `$iterator->first` - est-ce la première itération ?
- `$iterator->last` - est-ce la dernière itération ?
- `$iterator->counter` - compteur d'itérations, commence à 1
- `$iterator->counter0` - compteur d'itérations, démarre à 0
- `$iterator->odd` - cette itération est-elle impaire ?
- `$iterator->even` - cette itération est-elle paire ?
- `$iterator->parent` - l'itérateur qui entoure l'itérateur actuel
- `$iterator->nextValue` - l'élément suivant dans la boucle
- `$iterator->nextKey` - la clé de l'élément suivant dans la boucle


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

La latte est intelligente et `$iterator->last` fonctionne non seulement pour les tableaux, mais aussi lorsque la boucle passe sur un itérateur général où le nombre d'éléments n'est pas connu à l'avance.


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

Ces balises peuvent être utilisées à l'intérieur de la boucle `{foreach}`. Le contenu de `{first}` est rendu lors du premier passage.
Le contenu de `{last}` est rendu... pouvez-vous deviner ? Oui, pour le dernier passage. Ce sont en fait des raccourcis pour `{if $iterator->first}` et `{if $iterator->last}`.

Les balises peuvent également être écrites sous la forme [n:attributes |syntax#n:attributes]:

```latte
{foreach $rows as $row}
	{first}<h1>List of names</h1>{/first}

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

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

Le contenu du site `{sep}` est rendu si l'itération n'est pas la dernière, il convient donc pour imprimer des délimiteurs, tels que des virgules entre les éléments énumérés :

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

C'est plutôt pratique, non ?


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

Il simplifie le regroupement des données linéaires pendant l'itération dans une boucle foreach en effectuant l'itération dans une boucle imbriquée tant que la condition est remplie. [Lire les instructions dans le livre de cuisine |cookbook/iteratewhile].

Elle peut aussi remplacer élégamment `{first}` et `{last}` dans l'exemple ci-dessus :

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


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

Nous écrivons le cycle exactement de la même manière qu'en PHP :

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

La balise peut aussi être écrite comme [n:attribut |syntax#n:attributes]:

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


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

Là encore, nous écrivons le cycle exactement de la même manière qu'en PHP :

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

Ou comme [n:attribut |syntax#n:attributes]:

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

Une variante avec une condition dans la balise de fin correspond à la boucle do-while en PHP :

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


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

Il existe des balises spéciales que vous pouvez utiliser pour contrôler n'importe quelle boucle - `{continueIf ?}` et `{breakIf ?}` qui sautent à l'itération suivante et mettent fin à la boucle, respectivement, si les conditions sont remplies :

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


L'étiquette `{skipIf}` est très similaire à `{continueIf}`, mais n'incrémente pas le compteur. Il n'y a donc pas de trous dans la numérotation lorsque vous imprimez `$iterator->counter` et sautez certains éléments. De même, la clause {else} sera rendue lorsque vous sautez tous les éléments.

```latte
<ul>
	{foreach $people as $person}
		{skipIf $person->age < 18}
		<li>{$iterator->counter}. {$person->name}</li>
	{else}
		<li><em>Sorry, no adult users in this list</em></li>
	{/foreach}
</ul>
```


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

Termine le rendu d'un modèle ou d'un bloc lorsqu'une condition est remplie (c'est-à-dire une "sortie anticipée").

```latte
{exitIf !$messages}

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


Inclure des modèles .[#toc-including-templates]
===============================================


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

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

La balise `{include}` charge et rend le modèle spécifié. Dans notre langage PHP préféré, c'est comme ça :

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

Les templates inclus n'ont pas accès aux variables du contexte actif, mais ont accès aux variables globales.

Vous pouvez transmettre des variables au modèle inséré de la manière suivante :

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

Le nom du modèle peut être n'importe quelle expression PHP :

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

Le contenu inséré peut être modifié à l'aide de [filtres |syntax#filters]. L'exemple suivant supprime tous les éléments HTML et ajuste la casse :

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

L'[héritage du modèle |template inheritance] **n'est pas impliqué** dans ce processus par défaut. Bien que vous puissiez ajouter des balises de bloc aux modèles inclus, elles ne remplaceront pas les blocs correspondants dans le modèle dans lequel elles sont incluses. Considérez les inclusions comme des parties indépendantes et protégées de pages ou de modules. Ce comportement peut être modifié à l'aide du modificateur `with blocks`:

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

La relation entre le nom de fichier spécifié dans la balise et le fichier sur le disque est une question de [chargeur |extending-latte#Loaders].


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

Lorsque vous incluez un modèle créé par un utilisateur final, vous devez envisager de le mettre en sandbox (plus d'informations dans la [documentation sur le sandbox |sandbox]) :

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


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

.[note]
Voir aussi [`{block name}` |template-inheritance#blocks]

Les blocs sans nom permettent d'appliquer des [filtres |syntax#filters] à une partie du modèle. Par exemple, vous pouvez appliquer un filtre à [bandes |filters#strip] pour supprimer les espaces inutiles :

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


Traitement des exceptions .[#toc-exception-handling]
====================================================


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

Cette balise permet de créer très facilement des modèles robustes.

Si une exception se produit lors du rendu du bloc `{try}`, le bloc entier est jeté et le rendu se poursuit après :

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

Le contenu de la clause facultative `{else}` n'est rendu que lorsqu'une exception se produit :

```latte
{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
	{else}
	<p>Sorry, the tweets could not be loaded.</p>
{/try}
```

La balise peut également être écrite comme [n:attribut |syntax#n:attributes]:

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

Il est également possible de définir [son propre gestionnaire d'exception |develop#exception handler], par exemple pour la journalisation :


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

Le bloc `{try}` peut également être arrêté et sauté manuellement à l'aide de `{rollback}`. Il n'est donc pas nécessaire de vérifier toutes les données d'entrée à l'avance, et ce n'est que pendant le rendu que vous pouvez décider s'il est judicieux de rendre l'objet.

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


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


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

Nous allons créer de nouvelles variables dans le modèle avec la balise `{var}`:

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

{* Déclaration multiple *}
{var $name = 'John Smith', $age = 27}
```

La balise `{default}` fonctionne de manière similaire, sauf qu'elle crée des variables uniquement si elles n'existent pas :

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

Vous pouvez également spécifier des [types de variables |type-system]. Pour l'instant, ils sont informatifs et Latte ne les vérifie pas.

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


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

Tout comme une fonction déclare ses paramètres, un modèle peut déclarer ses variables à son début :

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

Les variables `$a` et `$b` sans valeur par défaut ont automatiquement une valeur par défaut de `null`. Les types déclarés sont toujours informatifs et Latte ne les vérifie pas.

En dehors de cela, les variables déclarées ne sont pas passées dans le modèle. C'est une différence par rapport à la balise `{default}`.


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

En utilisant la balise `{capture}`, vous pouvez capturer la sortie vers une variable :

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

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

La balise peut également s'écrire [n:attribut |syntax#n:attributes], comme n'importe quelle balise par paire :

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

La sortie HTML est stockée dans la variable `$var` sous la forme d'un objet `Latte\Runtime\Html` afin d'[éviter tout échappement indésirable |develop#disabling-auto-escaping-of-variable] lors de l'impression.


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


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

Utilisez la balise pour spécifier le type de contenu que le modèle représente. Les options sont les suivantes :

- `html` (type par défaut)
- `xml`
- `javascript`
- `css`
- `calendar` (iCal)
- `text`

Son utilisation est importante car elle définit l'[échappement contextuel |safety-first#context-aware-escaping] et ce n'est qu'alors que Latte peut s'échapper correctement. Par exemple, `{contentType xml}` passe en mode XML, `{contentType text}` désactive complètement l'échappement.

Si le paramètre est un type MIME complet, tel que `application/xml`, il envoie également un en-tête HTTP `Content-Type` au navigateur :

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


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

Spécifie l'endroit où l'exécution du code sera interrompue. Il est utilisé à des fins de débogage pour que le programmeur puisse inspecter l'environnement d'exécution et s'assurer que le code s'exécute comme prévu. Il prend en charge [Xdebug |https://xdebug.org]. En outre, vous pouvez spécifier une condition à laquelle le code doit être interrompu.

```latte
{debugbreak}                {* casse le programme *}

{debugbreak $counter == 1}  {* interrompt le programme si la condition est remplie *}
```


`{do}`
------

Exécute le code PHP et n'imprime rien. Comme pour toutes les autres balises, le code PHP est une expression unique, voir les [limitations de PHP |syntax#PHP Limitations in Latte].

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


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

Décharge une variable ou le contexte actuel.

```latte
{dump $name} {* vide la variable $name *}

{dump}       {* vide toutes les variables définies *}
```

.[caution]
Nécessite le paquet [Tracy |tracy:].


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

Permet d'exécuter n'importe quel code PHP. La balise doit être activée à l'aide de l'extension [RawPhpExtension |develop#RawPhpExtension].


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

Supprime les espaces blancs inutiles. Il est similaire au filtre [sans espace |filters#spaceless].

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

Sorties :

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

La balise peut aussi être écrite comme [n:attribut |syntax#n:attributes]:


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

Les balises Latte ne doivent pas nécessairement être entourées d'accolades simples uniquement. Vous pouvez choisir un autre séparateur, même au moment de l'exécution. Ceci est fait par `{syntax…}`, où le paramètre peut être :

- double : `{{...}}`
- off : désactive complètement les balises Latte

En utilisant la notation n:attribute, nous pouvons désactiver Latte pour un bloc JavaScript uniquement :

```latte
<script n:syntax="off">
	var obj = {var: 123}; // this isn't a tag any more
</script>
```

Latte peut être utilisé très confortablement en JavaScript, il suffit d'éviter les constructions comme dans cet exemple, où la lettre suit immédiatement `{`, voir [Latte en JavaScript ou CSS |recipes#Latte inside JavaScript or CSS].

Si vous désactivez Latte avec la balise `{syntax off}` (c'est-à-dire la balise, pas l'attribut n :), il ignorera strictement toutes les balises jusqu'à `{/syntax}`.


{trace}
-------

Lance une exception `Latte\RuntimeException`, dont la trace de pile est dans l'esprit des templates. Ainsi, au lieu d'appeler des fonctions et des méthodes, il s'agit d'appeler des blocs et d'insérer des templates. Si vous utilisez un outil permettant d'afficher clairement les exceptions lancées, tel que [Tracy |tracy:], vous verrez clairement la pile d'appel, y compris tous les arguments passés.


Aides de balises HTML .[#toc-html-tag-helpers]
==============================================


n:class
-------

Grâce à `n:class`, il est très facile de générer l'attribut HTML `class` exactement comme vous le souhaitez.

Exemple : J'ai besoin que l'élément actif ait la classe `active`:

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

Et j'ai également besoin que le premier élément ait les classes `first` et `main`:

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

Et tous les éléments doivent avoir la classe `list-item`:

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

Incroyablement simple, n'est-ce pas ?


n:attr
------

L'attribut `n:attr` peut générer des attributs HTML arbitraires avec la même élégance que [n:class |#n:class].

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

En fonction des valeurs renvoyées, il affiche eg :

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

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

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


n:tag
-----

L'attribut `n:tag` permet de modifier dynamiquement le nom d'un élément HTML.

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

Si `$heading === null`, la balise `<h1>` est imprimé sans changement. Sinon, le nom de l'élément est changé en la valeur de la variable, donc pour `$heading === 'h3'` il s'écrit :

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

Latte étant un système de templates sécurisé, il vérifie que le nouveau nom de balise est valide et ne contient pas de valeurs indésirables ou malveillantes.


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

Empêche l'impression d'un élément HTML vide, c'est-à-dire un élément ne contenant que des espaces blancs.

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

En fonction des valeurs de la variable `$error`, cet élément sera imprimé :

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

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


Traduction .[#toc-translation]
==============================

Pour que les balises de traduction fonctionnent, vous devez configurer [translator |develop#TranslatorExtension]. Vous pouvez également utiliser le [`translate` |filters#translate] pour la traduction.


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

Traduit les valeurs dans d'autres langues.

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

D'autres paramètres peuvent également être transmis au traducteur :

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


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

Překládá části šablony :

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

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

La balise peut aussi s'écrire [n:attribut |syntax#n:attributes], pour traduire l'intérieur de l'élément :

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

Latte Marqueurs

Résumé et description de toutes les balises intégrées de Latte.

Impression
{$var}, {...} ou {=...} imprime une variable ou une expression échappée
{$var|filter} imprime avec des filtres
{l} ou {r} imprime le caractère { or }
Conditions
{if}{elseif}{else}{/if} condition if
{ifset}{elseifset}{/ifset} condition ifset
{ifchanged}{/ifchanged} test si un changement est intervenu
{switch} {case} {default} {/switch} condition switch
n:else contenu alternatif pour les conditions
Boucles
{foreach}{/foreach} foreach
{for}{/for} for
{while}{/while} while
{continueIf $cond} continuer à l'itération suivante
{skipIf $cond} sauter l'itération de la boucle actuelle
{breakIf $cond} interrompt la boucle
{exitIf $cond} sortie anticipée
{first}{/first} est-ce la première itération ?
{last}{/last} est-ce la dernière itération ?
{sep}{/sep} la prochaine itération suivra-t-elle ?
{iterateWhile}{/iterateWhile} foreach structuré
$iterator variable spéciale dans la boucle foreach
Inclure d'autres modèles
{include 'file.latte'} inclut un modèle d'un autre fichier
{sandbox 'file.latte'} inclut un modèle en mode sandbox
Blocs, mises en page, héritage de modèles
{block} bloc anonyme
{block blockname} définition du bloc
{define blockname} Définition du bloc pour une utilisation future
{include blockname} Imprime le bloc
{include blockname from 'file.latte'} Imprime un bloc depuis un fichier
{import 'file.latte'} charge des blocs à partir d'un autre modèle
{layout 'file.latte'} / {extends} spécifie un fichier de mise en page
{embed}{/embed} charge le modèle ou le bloc et vous permet d'écraser les blocs
{ifset blockname}{/ifset} conditionne la définition d'un bloc
Traitement des exceptions
{try}{else}{/try} attrape les exceptions
{rollback} rejeter le bloc d'essai
Variables
{var $foo = value} création de variables
{default $foo = value} valeur par défaut quand la variable n'est pas déclarée
{parameters} déclare des variables, des types et des valeurs par défaut
{capture}{/capture} capture une section à une variable
Types
{varType} déclare le type de la variable
{varPrint} suggère des types de variables
{templateType} déclare les types de variables en utilisant une classe
{templatePrint} génère une classe avec des propriétés
Traduction
{_string} imprime la traduction
{translate}{/translate} traduit le contenu
Autres
{contentType} change le mode d'échappement et envoie l'en-tête HTTP
{debugbreak} met un point d'arrêt au code
{do} évalue une expression sans l'imprimer
{dump} Décharge les variables dans la barre de Tracy
{php} exécute n'importe quel code PHP
{spaceless}{/spaceless} supprime les espaces blancs inutiles
{syntax} change la syntaxe au moment de l'exécution
{trace} montre la trace de la pile
Aides pour les balises HTML
n:class Attribut de classe intelligent
n:attr attributs HTML intelligents
n:tag Nom dynamique de l'élément HTML
n:ifcontent Omettre une balise HTML vide
Disponible uniquement dans Nette Framework
n:href lien dans les éléments HTML <a>
{link} imprime un lien
{plink} imprime un lien vers un présentateur
{control} imprime un composant
{snippet}{/snippet} un snippet de modèle qui peut être envoyé par AJAX
{snippetArea} enveloppe des snippets
{cache}{/cache} met en cache une section de modèle
Disponible uniquement avec Nette Forms
{form}{/form} imprime un élément de formulaire
{label}{/label} imprime une étiquette d'entrée de formulaire
{input} imprime un élément de saisie de formulaire
{inputError} imprime un message d'erreur pour l'élément de saisie du formulaire
n:name active un élément de saisie HTML
{formContainer}{/formContainer} rendre le conteneur de formulaire

Impression de

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

Latte utilise la balise {=...} pour imprimer n'importe quelle expression sur la sortie. Si l'expression commence par une variable ou un appel de fonction, il n'est pas nécessaire d'écrire un signe égal. Ce qui, en pratique, signifie qu'il n'est presque jamais nécessaire de l'écrire :

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

Vous pouvez écrire tout ce que vous connaissez de PHP sous forme d'expression. Vous n'avez simplement pas besoin d'apprendre un nouveau langage. Par exemple :

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

Ne cherchez pas de sens dans l'exemple précédent, mais si vous en trouvez un, écrivez-nous :-)

Sortie d'échappement

Quelle est la tâche la plus importante d'un système de modèles ? Éviter les failles de sécurité. Et c'est exactement ce que fait Latte lorsque vous imprimez quelque chose en sortie. Il échappe automatiquement tout :

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

Pour être précis, Latte utilise l'échappement contextuel, qui est une fonctionnalité tellement importante et unique que nous lui avons consacré un chapitre séparé.

Et si vous imprimez du contenu codé en HTML à partir d'une source fiable ? Vous pouvez alors facilement désactiver l'échappement :

{$trustedHtmlString|noescape}

Une mauvaise utilisation du filtre noescape peut conduire à une vulnérabilité XSS ! Ne l'utilisez jamais sans être absolument sûr de ce que vous faites et que la chaîne que vous imprimez provient d'une source fiable.

Impression en JavaScript

Grâce à l'échappement contextuel, il est merveilleusement facile d'imprimer des variables en JavaScript, et Latte les échappera correctement.

La variable ne doit pas nécessairement être une chaîne de caractères, n'importe quel type de données est pris en charge, qui est ensuite encodé en JSON :

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

Génère :

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

C'est aussi la raison pour laquelle ne pas mettre les variables entre guillemets : Latte les ajoute autour des chaînes de caractères. Et si vous voulez mettre une variable de chaîne dans une autre chaîne, il suffit de les concaténer :

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

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

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

Filtres

L'expression imprimée peut être modifiée par des filtres. Par exemple, cet exemple convertit la chaîne en majuscules et la raccourcit à un maximum de 30 caractères :

{$string|upper|truncate:30}

Vous pouvez également appliquer des filtres à des parties d'une expression comme suit :

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

Conditions

{if} {elseif} {else}

Les conditions se comportent de la même manière que leurs équivalents en PHP. Vous pouvez utiliser les mêmes expressions que celles que vous connaissez en PHP, vous n'avez pas besoin d'apprendre un nouveau langage.

{if $product->inStock > Stock::Minimum}
	In stock
{elseif $product->isOnWay()}
	On the way
{else}
	Not available
{/if}

Comme toute balise de paire, une paire de {if} ... {/ if} peut être écrite comme n:attribut, par exemple :

<p n:if="$count > 0">In stock {$count} items</p>

Savez-vous que vous pouvez ajouter le préfixe tag- aux n:attributs ? La condition n'affectera alors que les balises HTML et le contenu situé entre elles sera toujours imprimé :

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

{* prints 'Hello' when $clickable is falsey *}
{* prints '<a href="...">Hello</a>' when $clickable is truthy *}

Bien.

n:else

Si vous écrivez la condition {if} ... {/if} sous la forme d'un n:attribut, vous avez la possibilité de spécifier une branche alternative en utilisant n:else:

<strong n:if="$count > 0">In stock {$count} items</strong>

<em n:else>not available</em>

L'attribut n:else peut également être utilisé en conjonction avec n:ifset, n:foreach, n:try, n:ifcontent, et n:ifchanged.

{/if $cond}

Vous serez peut-être surpris de constater que l'expression de la condition {if} peut également être spécifiée dans la balise de fin. Cela est utile dans les situations où nous ne connaissons pas encore la valeur de la condition à l'ouverture de la balise. Appelons cela une décision différée.

Par exemple, nous commençons à lister un tableau avec des enregistrements de la base de données, et ce n'est qu'après avoir terminé le rapport que nous nous rendons compte qu'il n'y avait aucun enregistrement dans la base de données. Nous mettons donc une condition dans la balise de fin {/if} et s'il n'y a pas d'enregistrement, rien ne sera imprimé :

{if}
	<h1>Printing rows from the database</h1>

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

Pratique, n'est-ce pas ?

Vous pouvez également utiliser {else} dans la condition différée, mais pas {elseif}.

{ifset} {elseifset}

Voir aussi {ifset block}

Utilisez la condition {ifset $var} pour déterminer si une variable (ou plusieurs variables) existe et a une valeur non nulle. C'est en fait la même chose que if (isset($var)) en PHP. Comme toute balise de paire, elle peut être écrite sous la forme n:attribut, alors montrons-la en exemple :

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

{ifchanged}

{ifchanged} vérifie si la valeur d'une variable a changé depuis la dernière itération de la boucle (foreach, for, ou while).

Si nous spécifions une ou plusieurs variables dans la balise, elle vérifiera si l'une d'entre elles a changé et imprimera le contenu en conséquence. Par exemple, l'exemple suivant imprime la première lettre d'un nom en tant qu'en-tête chaque fois qu'elle change lors de l'énumération des noms :

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

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

Toutefois, si aucun argument n'est fourni, le contenu rendu lui-même sera vérifié par rapport à son état précédent. Cela signifie que dans l'exemple précédent, nous pouvons omettre sans risque l'argument dans la balise. Et bien sûr, nous pouvons également utiliser n:attribute:

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

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

Vous pouvez également inclure une clause {else} à l'intérieur de {ifchanged}.

{switch} {case} {default}

Compare la valeur avec plusieurs options. Cette structure est similaire à la structure switch que vous connaissez de PHP. Cependant, Latte l'améliore :

  • utilise une comparaison stricte (===)
  • n'a pas besoin d'un break

C'est donc l'équivalent exact de la structure match fournie par PHP 8.0.

{switch $transport}
	{case train}
		By train
	{case plane}
		By plane
	{default}
		Differently
{/switch}

La clause {case} peut contenir plusieurs valeurs séparées par des virgules :

{switch $status}
{case $status::New}<b>new item</b>
{case $status::Sold, $status::Unknown}<i>not available</i>
{/switch}

Boucles

Dans Latte, toutes les boucles que vous connaissez de PHP sont à votre disposition : foreach, for et while.

{foreach}

Vous écrivez le cycle exactement de la même manière qu'en PHP :

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

En outre, il a quelques tweaks pratiques dont nous allons parler maintenant.

Par exemple, Latte vérifie que les variables créées n'écrasent pas accidentellement les variables globales du même nom. Cela vous sauvera lorsque vous supposerez que $lang est la langue actuelle de la page, et que vous ne réaliserez pas que foreach $langs as $lang a écrasé cette variable.

La boucle foreach peut également être écrite de manière très élégante et économique avec n:attribute:

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

Saviez-vous que vous pouvez ajouter le préfixe inner- au préfixe n:attribute ? Ainsi, seule la partie intérieure de l'élément sera répétée dans la boucle :

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

Donc ça imprime quelque chose comme :

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

{else}

La boucle foreach peut prendre une clause optionnelle {else} dont le texte est affiché si le tableau donné est vide :

<ul>
	{foreach $people as $person}
		<li>{$person->name}</li>
	{else}
		<li><em>Sorry, no users in this list</em></li>
	{/foreach}
</ul>

$iterator

À l'intérieur de la boucle foreach, la variable $iterator est initialisée. Elle contient des informations importantes sur la boucle en cours.

  • $iterator->first – est-ce la première itération ?
  • $iterator->last – est-ce la dernière itération ?
  • $iterator->counter – compteur d'itérations, commence à 1
  • $iterator->counter0 – compteur d'itérations, démarre à 0
  • $iterator->odd – cette itération est-elle impaire ?
  • $iterator->even – cette itération est-elle paire ?
  • $iterator->parent – l'itérateur qui entoure l'itérateur actuel
  • $iterator->nextValue – l'élément suivant dans la boucle
  • $iterator->nextKey – la clé de l'élément suivant dans la boucle
{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}

La latte est intelligente et $iterator->last fonctionne non seulement pour les tableaux, mais aussi lorsque la boucle passe sur un itérateur général où le nombre d'éléments n'est pas connu à l'avance.

{first} {last} {sep}

Ces balises peuvent être utilisées à l'intérieur de la boucle {foreach}. Le contenu de {first} est rendu lors du premier passage. Le contenu de {last} est rendu… pouvez-vous deviner ? Oui, pour le dernier passage. Ce sont en fait des raccourcis pour {if $iterator->first} et {if $iterator->last}.

Les balises peuvent également être écrites sous la forme n:attributes:

{foreach $rows as $row}
	{first}<h1>List of names</h1>{/first}

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

	<hr n:last>
{/foreach}

Le contenu du site {sep} est rendu si l'itération n'est pas la dernière, il convient donc pour imprimer des délimiteurs, tels que des virgules entre les éléments énumérés :

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

C'est plutôt pratique, non ?

{iterateWhile}

Il simplifie le regroupement des données linéaires pendant l'itération dans une boucle foreach en effectuant l'itération dans une boucle imbriquée tant que la condition est remplie. Lire les instructions dans le livre de cuisine.

Elle peut aussi remplacer élégamment {first} et {last} dans l'exemple ci-dessus :

{foreach $rows as $row}
	<table>

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

	</table>
{/foreach}

{for}

Nous écrivons le cycle exactement de la même manière qu'en PHP :

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

La balise peut aussi être écrite comme n:attribut:

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

{while}

Là encore, nous écrivons le cycle exactement de la même manière qu'en PHP :

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

Ou comme n:attribut:

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

Une variante avec une condition dans la balise de fin correspond à la boucle do-while en PHP :

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

{continueIf} {skipIf} {breakIf}

Il existe des balises spéciales que vous pouvez utiliser pour contrôler n'importe quelle boucle – {continueIf ?} et {breakIf ?} qui sautent à l'itération suivante et mettent fin à la boucle, respectivement, si les conditions sont remplies :

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

L'étiquette {skipIf} est très similaire à {continueIf}, mais n'incrémente pas le compteur. Il n'y a donc pas de trous dans la numérotation lorsque vous imprimez $iterator->counter et sautez certains éléments. De même, la clause {else} sera rendue lorsque vous sautez tous les éléments.

<ul>
	{foreach $people as $person}
		{skipIf $person->age < 18}
		<li>{$iterator->counter}. {$person->name}</li>
	{else}
		<li><em>Sorry, no adult users in this list</em></li>
	{/foreach}
</ul>

{exitIf}

Termine le rendu d'un modèle ou d'un bloc lorsqu'une condition est remplie (c'est-à-dire une „sortie anticipée“).

{exitIf !$messages}

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

Inclure des modèles

{include 'file.latte'}

Voir aussi {include block}

La balise {include} charge et rend le modèle spécifié. Dans notre langage PHP préféré, c'est comme ça :

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

Les templates inclus n'ont pas accès aux variables du contexte actif, mais ont accès aux variables globales.

Vous pouvez transmettre des variables au modèle inséré de la manière suivante :

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

Le nom du modèle peut être n'importe quelle expression PHP :

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

Le contenu inséré peut être modifié à l'aide de filtres. L'exemple suivant supprime tous les éléments HTML et ajuste la casse :

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

L'héritage du modèle n'est pas impliqué dans ce processus par défaut. Bien que vous puissiez ajouter des balises de bloc aux modèles inclus, elles ne remplaceront pas les blocs correspondants dans le modèle dans lequel elles sont incluses. Considérez les inclusions comme des parties indépendantes et protégées de pages ou de modules. Ce comportement peut être modifié à l'aide du modificateur with blocks:

{include 'template.latte' with blocks}

La relation entre le nom de fichier spécifié dans la balise et le fichier sur le disque est une question de chargeur.

{sandbox}

Lorsque vous incluez un modèle créé par un utilisateur final, vous devez envisager de le mettre en sandbox (plus d'informations dans la documentation sur le sandbox) :

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

{block}

Voir aussi {block name}

Les blocs sans nom permettent d'appliquer des filtres à une partie du modèle. Par exemple, vous pouvez appliquer un filtre à bandes pour supprimer les espaces inutiles :

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

Traitement des exceptions

{try}

Cette balise permet de créer très facilement des modèles robustes.

Si une exception se produit lors du rendu du bloc {try}, le bloc entier est jeté et le rendu se poursuit après :

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

Le contenu de la clause facultative {else} n'est rendu que lorsqu'une exception se produit :

{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
	{else}
	<p>Sorry, the tweets could not be loaded.</p>
{/try}

La balise peut également être écrite comme n:attribut:

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

Il est également possible de définir son propre gestionnaire d'exception, par exemple pour la journalisation :

{rollback}

Le bloc {try} peut également être arrêté et sauté manuellement à l'aide de {rollback}. Il n'est donc pas nécessaire de vérifier toutes les données d'entrée à l'avance, et ce n'est que pendant le rendu que vous pouvez décider s'il est judicieux de rendre l'objet.

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

Variables

{var} {default}

Nous allons créer de nouvelles variables dans le modèle avec la balise {var}:

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

{* Déclaration multiple *}
{var $name = 'John Smith', $age = 27}

La balise {default} fonctionne de manière similaire, sauf qu'elle crée des variables uniquement si elles n'existent pas :

{default $lang = 'cs'}

Vous pouvez également spécifier des types de variables. Pour l'instant, ils sont informatifs et Latte ne les vérifie pas.

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

{parameters}

Tout comme une fonction déclare ses paramètres, un modèle peut déclarer ses variables à son début :

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

Les variables $a et $b sans valeur par défaut ont automatiquement une valeur par défaut de null. Les types déclarés sont toujours informatifs et Latte ne les vérifie pas.

En dehors de cela, les variables déclarées ne sont pas passées dans le modèle. C'est une différence par rapport à la balise {default}.

{capture}

En utilisant la balise {capture}, vous pouvez capturer la sortie vers une variable :

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

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

La balise peut également s'écrire n:attribut, comme n'importe quelle balise par paire :

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

La sortie HTML est stockée dans la variable $var sous la forme d'un objet Latte\Runtime\Html afin d'éviter tout échappement indésirable lors de l'impression.

Autres

{contentType}

Utilisez la balise pour spécifier le type de contenu que le modèle représente. Les options sont les suivantes :

  • html (type par défaut)
  • xml
  • javascript
  • css
  • calendar (iCal)
  • text

Son utilisation est importante car elle définit l'échappement contextuel et ce n'est qu'alors que Latte peut s'échapper correctement. Par exemple, {contentType xml} passe en mode XML, {contentType text} désactive complètement l'échappement.

Si le paramètre est un type MIME complet, tel que application/xml, il envoie également un en-tête HTTP Content-Type au navigateur :

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

{debugbreak}

Spécifie l'endroit où l'exécution du code sera interrompue. Il est utilisé à des fins de débogage pour que le programmeur puisse inspecter l'environnement d'exécution et s'assurer que le code s'exécute comme prévu. Il prend en charge Xdebug. En outre, vous pouvez spécifier une condition à laquelle le code doit être interrompu.

{debugbreak}                {* casse le programme *}

{debugbreak $counter == 1}  {* interrompt le programme si la condition est remplie *}

{do}

Exécute le code PHP et n'imprime rien. Comme pour toutes les autres balises, le code PHP est une expression unique, voir les limitations de PHP.

{do $num++}

{dump}

Décharge une variable ou le contexte actuel.

{dump $name} {* vide la variable $name *}

{dump}       {* vide toutes les variables définies *}

Nécessite le paquet Tracy.

{php}

Permet d'exécuter n'importe quel code PHP. La balise doit être activée à l'aide de l'extension RawPhpExtension.

{spaceless}

Supprime les espaces blancs inutiles. Il est similaire au filtre sans espace.

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

Sorties :

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

La balise peut aussi être écrite comme n:attribut:

{syntax}

Les balises Latte ne doivent pas nécessairement être entourées d'accolades simples uniquement. Vous pouvez choisir un autre séparateur, même au moment de l'exécution. Ceci est fait par {syntax…}, où le paramètre peut être :

  • double : {{...}}
  • off : désactive complètement les balises Latte

En utilisant la notation n:attribute, nous pouvons désactiver Latte pour un bloc JavaScript uniquement :

<script n:syntax="off">
	var obj = {var: 123}; // this isn't a tag any more
</script>

Latte peut être utilisé très confortablement en JavaScript, il suffit d'éviter les constructions comme dans cet exemple, où la lettre suit immédiatement {, voir Latte en JavaScript ou CSS.

Si vous désactivez Latte avec la balise {syntax off} (c'est-à-dire la balise, pas l'attribut n :), il ignorera strictement toutes les balises jusqu'à {/syntax}.

{trace}

Lance une exception Latte\RuntimeException, dont la trace de pile est dans l'esprit des templates. Ainsi, au lieu d'appeler des fonctions et des méthodes, il s'agit d'appeler des blocs et d'insérer des templates. Si vous utilisez un outil permettant d'afficher clairement les exceptions lancées, tel que Tracy, vous verrez clairement la pile d'appel, y compris tous les arguments passés.

Aides de balises HTML

n:class

Grâce à n:class, il est très facile de générer l'attribut HTML class exactement comme vous le souhaitez.

Exemple : J'ai besoin que l'élément actif ait la classe active:

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

Et j'ai également besoin que le premier élément ait les classes first et main:

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

Et tous les éléments doivent avoir la classe list-item:

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

Incroyablement simple, n'est-ce pas ?

n:attr

L'attribut n:attr peut générer des attributs HTML arbitraires avec la même élégance que n:class.

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

En fonction des valeurs renvoyées, il affiche eg :

<input type="checkbox">

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

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

n:tag

L'attribut n:tag permet de modifier dynamiquement le nom d'un élément HTML.

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

Si $heading === null, la balise <h1> est imprimé sans changement. Sinon, le nom de l'élément est changé en la valeur de la variable, donc pour $heading === 'h3' il s'écrit :

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

Latte étant un système de templates sécurisé, il vérifie que le nouveau nom de balise est valide et ne contient pas de valeurs indésirables ou malveillantes.

n:ifcontent

Empêche l'impression d'un élément HTML vide, c'est-à-dire un élément ne contenant que des espaces blancs.

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

En fonction des valeurs de la variable $error, cet élément sera imprimé :

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

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

Traduction

Pour que les balises de traduction fonctionnent, vous devez configurer translator. Vous pouvez également utiliser le translate pour la traduction.

{_...}

Traduit les valeurs dans d'autres langues.

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

D'autres paramètres peuvent également être transmis au traducteur :

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

{translate}

Překládá části šablony :

<h1>{translate}Order{/translate}</h1>

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

La balise peut aussi s'écrire n:attribut, pour traduire l'intérieur de l'élément :

<h1 n:translate>Order</h1>