Latte Tags

An overview and description of all the tags available by default in the Latte templating system.

Printing
{$var}, {...} or {=...} prints an escaped variable or expression
{$var|filter} prints with filters applied
{l} or {r} prints the { or } character
Conditions
{if}{elseif}{else}{/if} if condition
{ifset}{elseifset}{/ifset} ifset condition
{ifchanged}{/ifchanged} tests if a value has changed
{switch} {case} {default} {/switch} switch condition
n:else alternative content for conditions
Loops
{foreach}{/foreach} foreach
{for}{/for} for
{while}{/while} while
{continueIf $cond} continue to the next iteration
{skipIf $cond} skip the current loop iteration
{breakIf $cond} break the loop
{exitIf $cond} early exit
{first}{/first} is it the first iteration?
{last}{/last} is it the last iteration?
{sep}{/sep} will the next iteration follow?
{iterateWhile}{/iterateWhile} structured foreach
$iterator special variable inside the foreach loop
Including Other Templates
{include 'file.latte'} includes a template from another file
{sandbox 'file.latte'} includes a template in sandbox mode
Blocks, Layouts, Template Inheritance
{block} anonymous block
{block blockname} defines a block
{define blockname} defines a block for later use
{include blockname} renders a block
{include blockname from 'file.latte'} renders a block from a file
{import 'file.latte'} imports blocks from a template
{layout 'file.latte'} / {extends} specifies a layout file
{embed}{/embed} embeds a template or block and allows overriding blocks
{ifset blockname}{/ifset} condition checking if a block exists
Exception Handling
{try}{else}{/try} catching exceptions
{rollback} discards the try block
Variables
{var $foo = value} variable creation
{default $foo = value} creates a variable if it doesn't exist
{parameters} declares variables, types, and default values
{capture}{/capture} captures output into a variable
Types
{varType} declares the type of a variable
{varPrint} suggests variable types
{templateType} declares variable types based on a class
{templatePrint} suggests a class with variable types
Translation
{_...} prints translation
{translate}{/translate} translates the content
Others
{contentType} switches escaping and sends HTTP header
{debugbreak} places a breakpoint in the code
{do} executes code without printing anything
{dump} dumps variables to the Tracy Bar
{php} executes any PHP code
{spaceless}{/spaceless} removes unnecessary whitespace
{syntax} changes syntax at runtime
{trace} displays stack trace
HTML Coder Helpers
n:class dynamic HTML class attribute
n:attr dynamic HTML attributes
n:tag dynamic HTML element name
n:ifcontent omits empty HTML tag
Available only in Nette Framework
n:href link used in <a> HTML elements
{link} prints a link
{plink} prints a link to a presenter
{control} renders a component
{snippet}{/snippet} a template snippet that can be sent via AJAX
{snippetArea} snippet wrapper
{cache}{/cache} caches a part of the template
Available only with Nette Forms
{form}{/form} renders form tags
{label}{/label} renders a form control label
{input} renders a form control
{inputError} prints the error message of a form control
n:name activates a form control
{formContainer}{/formContainer} renders a form container

Printing

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

In Latte, the {=...} tag is used to print any expression to the output. Latte cares about your comfort, so if the expression starts with a variable or a function call, there's no need to write the equals sign. Which in practice means it almost never needs to be written:

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

You can write anything you know from PHP as an expression. You simply don't have to learn a new language. For example:

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

Please don't look for any meaning in the previous example, but if you find one, let us know :-)

Output Escaping

What is the most important task of a templating system? To prevent security vulnerabilities. And that's exactly what Latte does whenever you print something. It automatically escapes it:

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

To be precise, Latte uses context-aware escaping, which is such an important and unique feature that we've dedicated a separate chapter to it.

And what if you're printing HTML-encoded content from a trusted source? Then you can easily disable escaping:

{$trustedHtmlString|noescape}

Misuse of the noescape filter can lead to an XSS vulnerability! Never use it unless you are absolutely sure what you are doing and that the string you are printing comes from a trusted source.

Printing in JavaScript

Thanks to context-aware escaping, it's wonderfully easy to print variables inside JavaScript, and Latte will handle the proper escaping.

The variable doesn't have to be a string; any data type is supported, which is then encoded as JSON:

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

Generates:

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

This is also why you should not write quotes around the variable: Latte adds them for strings automatically. And if you want to insert a string variable into another string, simply concatenate them:

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

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

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

Filters

The printed expression can be modified by filters. For example, this converts the string to uppercase and shortens it to a maximum of 30 characters:

{$string|upper|truncate:30}

You can also apply filters to parts of an expression like this:

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

Conditions

{if} {elseif} {else}

Conditions behave the same way as their PHP counterparts. You can use the same expressions you know from PHP; you don't have to learn a new language.

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

Like any pair tag, the {if} ... {/if} pair can also be written using an n:attribute, for example:

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

Did you know you can add the tag- prefix to n:attributes? Then the condition will only affect the printing of HTML tags, and the content between them will always be printed:

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

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

Awesome.

n:else

If you write the {if} ... {/if} condition in the form of an n:attribute, you have the option to specify an alternative branch using n:else:

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

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

The n:else attribute can also be used in conjunction with n:ifset, n:foreach, n:try, n:ifcontent, and n:ifchanged.

{/if $cond}

You might be surprised that the expression in the {if} condition can also be specified in the closing tag. This is useful in situations where we don't yet know its value when opening the condition. Let's call it a deferred decision.

For example, we start listing a table with records from the database, and only after completing the output do we realize that there were no records in the database. So, we put the condition in the closing tag {/if}, and if there are no records, none of it will be printed:

{if}
	<h1>List of rows from the database</h1>

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

Handy, isn't it?

You can also use {else} in the deferred condition, but not {elseif}.

{ifset} {elseifset}

See also {ifset block}

Use the {ifset $var} condition to determine if a variable (or multiple variables) exists and has a non-null value. It's actually the same as if (isset($var)) in PHP. Like any pair tag, it can also be written using an n:attribute, so let's show an example:

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

{ifchanged}

{ifchanged} checks if the value of a variable has changed since the last iteration in a loop (foreach, for, or while).

If we provide one or more variables in the tag, it checks if any of them have changed and prints the content accordingly. For example, the following example prints the first letter of a name as a heading each time it changes during the listing of names:

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

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

However, if no argument is given, the rendered content itself will be checked against its previous state. This means that in the previous example, we can safely omit the argument in the tag. And of course, we can also use an n:attribute:

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

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

An {else} clause can also be used inside {ifchanged}.

{switch} {case} {default}

Compares a value with multiple options. This is similar to the switch statement known from PHP. However, Latte improves it:

  • uses strict comparison (===)
  • does not require break

It is thus the exact equivalent of the match structure introduced in PHP 8.0.

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

The {case} clause can contain multiple values separated by commas:

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

Loops

In Latte, you'll find all the loops you know from PHP: foreach, for, and while.

{foreach}

You write the loop exactly the same way as in PHP:

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

Additionally, it has a few handy features we'll discuss now.

For example, Latte checks that created variables do not accidentally overwrite global variables of the same name. This saves you from situations where you expect $lang to contain the current language of the page, and you don't realize that foreach $langs as $lang has overwritten that variable.

The foreach loop can also be written very elegantly and economically using an n:attribute:

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

Did you know you can add the inner- prefix to n:attributes? Then only the inner part of the element will be repeated in the loop:

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

So it prints something like:

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

{else}

Inside the foreach loop, you can specify an {else} clause, whose content is displayed if the loop is empty:

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

$iterator

Inside the foreach loop, Latte creates the $iterator variable, which allows us to find useful information about the ongoing loop:

  • $iterator->first – is this the first iteration?
  • $iterator->last – is this the last iteration?
  • $iterator->counter – iteration counter, starting from one
  • $iterator->counter0 – iteration counter, starting from zero
  • $iterator->odd – is this an odd iteration?
  • $iterator->even – is this an even iteration?
  • $iterator->parent – the iterator surrounding the current one
  • $iterator->nextValue – the next item in the loop
  • $iterator->nextKey – the key of the next item in the loop
{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 is smart, and $iterator->last works not only for arrays but also when the loop runs over a general iterator where the number of items is not known in advance.

{first} {last} {sep}

These tags can be used inside the {foreach} loop. The content of {first} is rendered if it's the first iteration. The content of {last} is rendered… can you guess? Yes, if it's the last iteration. These are actually shortcuts for {if $iterator->first} and {if $iterator->last}.

The tags can also be elegantly used as n:attributes:

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

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

	<hr n:last>
{/foreach}

The content of the {sep} tag is rendered if the iteration is not the last, making it suitable for rendering delimiters, such as commas between listed items:

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

That's quite practical, isn't it?

{iterateWhile}

Simplifies the grouping of linear data during iteration in a foreach loop by performing the iteration in a nested loop as long as the condition is met. Read the detailed instructions.

It can also elegantly replace {first} and {last} in the example above:

{foreach $rows as $row}
	<table>

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

	</table>
{/foreach}

See also the batch and group filters.

{for}

We write the loop exactly the same way as in PHP:

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

The tag can also be written as an n:attribute:

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

{while}

Again, we write the loop exactly the same way as in PHP:

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

Or as an n:attribute:

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

A variant with a condition in the closing tag is also possible, corresponding to the do-while loop in PHP:

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

{continueIf} {skipIf} {breakIf}

Special tags {continueIf ?} and {breakIf ?} can be used to control any loop. They jump to the next iteration or end the loop, respectively, if the condition is met:

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

The {skipIf} tag is very similar to {continueIf}, but it does not increment the $iterator->counter. This prevents gaps in numbering when printing the counter and skipping some items. Also, the {else} clause will be rendered if all items are skipped.

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

{exitIf}

Ends the rendering of a template or block when a condition is met (i.e., “early exit”).

{exitIf !$messages}

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

Including Templates

{include 'file.latte'}

See also {include block}

The {include} tag loads and renders the specified template. In our favorite PHP language, it's something like:

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

Included templates do not have access to the variables of the active context, but they do have access to the global variables.

You can pass variables to the included template like this:

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

The template name can be any PHP expression:

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

The included content can be modified using filters. The following example removes all HTML and adjusts the case:

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

By default, template inheritance is not involved in this. Although you can use blocks in included templates, they will not replace corresponding blocks in the template they are included into. Think of included templates as independent, shielded parts of pages or modules. This behavior can be changed using the with blocks modifier:

{include 'template.latte' with blocks}

The relationship between the file name specified in the tag and the file on disk depends on the loader.

{sandbox}

When including a template created by an end user, you should consider sandboxing it (more information in the sandbox documentation):

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

{block}

See also {block name}

Blocks without a name provide the ability to apply filters to a part of the template. For example, you can apply a strip filter to remove unnecessary spaces:

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

Exception Handling

{try}

Thanks to this tag, it's extremely easy to create robust templates.

If an exception occurs during the rendering of the {try} block, the entire block is discarded, and rendering continues after it:

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

The content of the optional {else} clause is rendered only when an exception occurs:

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

The tag can also be written as an n:attribute:

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

It's also possible to define a custom exception handler, for example, for logging purposes.

{rollback}

The {try} block can also be stopped and skipped manually using {rollback}. This way, you don't have to check all input data in advance, and only during rendering can you decide that the object shouldn't be rendered at all:

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

Variables

{var} {default}

We create new variables in the template using the {var} tag:

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

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

The {default} tag works similarly, but it creates variables only if they do not exist. If a variable already exists and contains the value null, it will not be overwritten:

{default $lang = 'en'}

You can also specify variable types. For now, they are informative, and Latte does not check them.

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

{parameters}

Just as a function declares its parameters, a template can declare its variables at the beginning:

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

Variables $a and $b without a specified default value automatically have a default value of null. The declared types are currently informative, and Latte does not check them.

Variables other than those declared are not passed to the template. This differs from the {default} tag.

{capture}

Captures the output into a variable:

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

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

Like any pair tag, this tag can also be written as an n:attribute:

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

The HTML output is stored in the $var variable as a Latte\Runtime\Html object to prevent unwanted escaping when printing.

Others

{contentType}

Use this tag to specify the type of content the template represents. The options are:

  • html (default type)
  • xml
  • javascript
  • css
  • calendar (iCal)
  • text

Its use is important because it sets context-sensitive escaping and only then can Latte escape correctly. For example, {contentType xml} switches to XML mode, {contentType text} turns off escaping completely.

If the parameter is a full MIME type, such as application/xml, it also sends the Content-Type HTTP header to the browser:

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

{debugbreak}

Specifies a point where program execution will pause. It is used for debugging purposes, allowing the programmer to inspect the runtime environment and ensure the code runs as expected. It supports Xdebug. You can also add a condition that determines when the program should pause.

{debugbreak}                {* pauses the program *}

{debugbreak $counter == 1}  {* pauses the program if the condition is met *}

{do}

Executes PHP code and prints nothing. As with all other tags, PHP code means a single expression, see PHP Limitations.

{do $num++}

{dump}

Dumps a variable or the current context.

{dump $name} {* Dumps the $name variable *}

{dump}       {* Dumps all currently defined variables *}

Requires the Tracy library.

{php}

Allows executing any PHP code. The tag must be activated using the RawPhpExtension extension.

{spaceless}

Removes unnecessary whitespace from the output. It works similarly to the spaceless filter.

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

Generates:

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

The tag can also be written as an n:attribute.

{syntax}

Latte tags don't have to be enclosed only in single curly braces. You can choose another separator, even at runtime. This is done using {syntax …}, where the parameter can be:

  • double: {{...}}
  • off: completely disables Latte tag processing

Using n:attributes, you can disable Latte for just one block of JavaScript, for example:

<script n:syntax="off">
	var obj = {var: 123}; // this is no longer a tag
</script>

Latte can be used very comfortably inside JavaScript, just avoid constructs like in this example, where a letter immediately follows {, see Latte inside JavaScript or CSS.

If you disable Latte using {syntax off} (i.e., the tag, not the n:attribute), it will strictly ignore all tags up to {/syntax}.

{trace}

Throws a Latte\RuntimeException exception, whose stack trace follows the spirit of templates. Thus, instead of function and method calls, it involves block calls and template inclusions. If you use a tool for clear display of thrown exceptions, such as Tracy, you will clearly see the call stack, including all passed arguments.

HTML Coder Helpers

n:class

Thanks to n:class, it's very easy to generate the HTML class attribute exactly as needed.

Example: I need the active element to have the class active:

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

And further, I need the first element to have the classes first and main:

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

And all elements should have the class list-item:

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

Amazingly simple, isn't it?

n:attr

The n:attr attribute can generate arbitrary HTML attributes with the same elegance as n:class.

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

Depending on the returned values, it prints, for example:

<input type="checkbox">

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

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

n:tag

The n:tag attribute can dynamically change the name of an HTML element.

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

If $heading === null, the <h1> tag is printed without change. Otherwise, the element name is changed to the value of the variable, so for $heading === 'h3', it writes:

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

Because Latte is a secure templating system, it checks that the new tag name is valid and does not contain any unwanted or malicious values.

n:ifcontent

Prevents an empty HTML element from being printed, i.e., an element containing nothing but whitespace.

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

Depending on the value of the variable $error, this will print:

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

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

Translation

For the translation tags to work, you need to activate the translator. You can also use the translate filter for translation.

{_...}

Translates values into other languages.

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

Other parameters can also be passed to the translator:

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

{translate}

Translates parts of the template:

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

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

The tag can also be written as an n:attribute, to translate the inside of the element:

<h1 n:translate>Order</h1>
version: 3.0 2.x