Latte Tags

Summary and description of all Latte built-in tags.

Printing
{$var}, {...} or {=...} prints an escaped variable or expression
{$var|filter} prints with filters
{l} or {r} prints { or } character
Conditions
{if}{elseif}{else}{/if} condition if
{ifset}{elseifset}{/ifset} condition ifset
{ifchanged}{/ifchanged} test if there has been a change
{switch} {case} {default} {/switch} condition switch
n:else alternative content for conditions
Loops
{foreach}{/foreach} foreach
{for}{/for} for
{while}{/while} while
{continueIf $cond} continue to next iteration
{skipIf $cond} skip the current loop iteration
{breakIf $cond} breaks loop
{exitIf $cond} early exit
{first}{/first} is it the first iteration?
{last}{/last} is it the last iteration?
{sep}{/sep} will next iteration follow?
{iterateWhile}{/iterateWhile} structured foreach
$iterator special variable inside foreach loop
Including other Templates
{include 'file.latte'} includes a template from other file
{sandbox 'file.latte'} includes a template in sandbox mode
Blocks, layouts, template inheritance
{block} anonymous block
{block blockname} block definition
{define blockname} block defintion for future use
{include blockname} prints block
{include blockname from 'file.latte'} prints a block from file
{import 'file.latte'} loads blocks from another template
{layout 'file.latte'} / {extends} specifies a layout file
{embed}{/embed} loads the template or block and allows you to overwrite the blocks
{ifset blockname}{/ifset} condition if block is defined
Exception handling
{try}{else}{/try} catching exceptions
{rollback} discards try block
Variables
{var $foo = value} variable creation
{default $foo = value} default value when variable isn't declared
{parameters} declares variables, types a default values
{capture}{/capture} captures a section to a variable
Types
{varType} declares type of variable
{varPrint} suggests types of variables
{templateType} declares types of variables using class
{templatePrint} generates class with properties
Translation
{_string} prints translated
{translate}{/translate} translates the content
Others
{contentType} switches the escaping mode and sends HTTP header
{debugbreak} sets breakpoint to the code
{do} evaluates an expression without printing it
{dump} dumps variables to the Tracy Bar
{php} executes any PHP code
{spaceless}{/spaceless} removes unnecessary whitespace
{syntax} switches the syntax at runtime
{trace} shows stack trace
HTML tag helpers
n:class smart class attribute
n:attr smart HTML attributes
n:tag dynamic name of HTML element
n:ifcontent omit empty HTML tag
Available only in Nette Framework
n:href link in <a> HTML elements
{link} prints a link
{plink} prints a link to a presenter
{control} prints a component
{snippet}{/snippet} a template snippet that can be sent by AJAX
{snippetArea} snippets envelope
{cache}{/cache} caches a template section
Available only with Nette Forms
{form}{/form} prints a form element
{label}{/label} prints a form input label
{input} prints a form input element
{inputError} prints error message for form input element
n:name activates an HTML input element
{formContainer}{/formContainer} rendering the form container

Printing

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

Latte uses the {=...} tag to print any expression to the output. If the expression starts with a variable or function call, there is no need to write an equal sign. Which in practice means that 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 just 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 there, write to us :-)

Escaping Output

What is the most important task of a template system? To avoid security holes. And that's exactly what Latte does whenever you print something to output. It automatically escapes everything:

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

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

And if you print HTML-encoded content from a trusted source? Then you can easily turn off 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-sensitive escaping, it is wonderfully easy to print variables inside JavaScript, and Latte will properly escape them.

The variable does not 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 the reason why do not put variable in quotes: Latte adds them around strings. And if you want to put 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 example converts the string to uppercase and shorten it to a maximum of 30 characters:

{$string|upper|truncate:30}

You can also apply filters to parts of an expression as follows:

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

Conditions

{if} {elseif} {else}

Conditions behave the same way as their PHP counterparts. You can use the same expressions as 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, a pair of {if} ... {/ if} can be written as n:attribute, for example:

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

Do you know that you can add prefix tag- to n:attributes? Then the condition will affects only the 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 *}

Nice.

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 may be surprised that the expression in the {if} condition can also be specified in the end tag. This is useful in situations where we do not yet know the value of the condition when tag is opened. Let's call it a deferred decision.

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

{if}
	<h1>Printing 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, this can be written in the form of n:attribute, so let's show it in 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 the loop (foreach, for, or while).

If we specify one or more variables in the tag, it will check if any of them have changed and prints the contents accordingly. For example, the following example prints the first letter of a name as a heading each time it changes when listing 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 n:attribute:

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

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

You can also include a {else} clause inside the {ifchanged}.

{switch} {case} {default}

Compares value with multiple options. This is similar to the switch structure you know from PHP. However, Latte improves it:

  • uses strict comparison (===)
  • does not need a break

So it is the exact equivalent of the match structure that PHP 8.0 comes with.

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

Clause {case} 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, all the loops you know from PHP are available to you: foreach, for and while.

{foreach}

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

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

In addition, he has some handy tweaks that we will talk about now.

For example, Latte checks that created variables do not accidentally overwrite global variables of the same name. This will save you when you assume that $lang is 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 with n:attribute:

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

Did you know that you can prepend the inner- prefix to n:attributes? Now then only the inside 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}

The foreach loop can take an optional {else} clause whose text is displayed if the given array is empty:

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

$iterator

Inside the foreach loop the $iterator variable is initialized. It holds important information about the current loop.

  • $iterator->first – is this the first iteration?
  • $iterator->last – is this the last iteration?
  • $iterator->counter – iteration counter, starts from 1
  • $iterator->counter0 – iteration counter, starts from 0
  • $iterator->odd – is this iteration odd?
  • $iterator->even – is this iteration even?
  • $iterator->parent – the iterator surrounding the current one
  • $iterator->nextValue – the next item in the loop
  • $iterator->nextKey – the key of 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}

The 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 contents of {first} are rendered for the first pass. The contents of {last} are rendered … can you guess? Yes, for the last pass. These are actually shortcuts for {if $iterator->first} and {if $iterator->last}.

The tags can also be written as n:attributes:

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

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

	<hr n:last>
{/foreach}

The contents of the {sep} are rendered if the iteration is not the last, so it is suitable for printing delimiters, such as commas between listed items:

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

That's pretty practical, isn't it?

{iterateWhile}

It 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 instructions in cookbook.

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}

{for}

We write the cycle in 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 n:attribute:

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

{while}

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

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

Or as n:attribute:

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

A variant with a condition in the end tag corresponds to the do-while loop in PHP:

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

{continueIf} {skipIf} {breakIf}

There are special tags you can use to control any loop – {continueIf ?} and {breakIf ?} which jump to the next iteration and end the loop, respectively, if the conditions are met:

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

Tag {skipIf} is very similar to {continueIf}, but does not increment the counter. So there are no holes in the numbering when you print $iterator->counter and skip some items. Also the {else} clause will be rendered when you skip all items.

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

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 like:

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

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

You can pass variables to the inserted template in the following way:

{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 inserted content can be modified using filters. The following example removes all HTML stuff and adjusts the case:

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

The template inheritance is not involved in this by default. While you can add block tags to templates that are included, they will not replace matching blocks in the template they are included into. Think of includes as independent and shielded parts of pages or modules. This behavior can be changed using the modifier with blocks:

{include 'template.latte' with blocks}

The relationship between the file name specified in the tag and the file on disk is a matter of 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 serve to the ability to apply filters to a part of 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}

This tags makes it extremely easy to build robust templates.

If an exception occurs while rendering the {try} block, the entire block is thrown away and rendering will continue after it:

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

The contents of the optional clause {else} are 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 n:attribute:

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

It is also possible to define own exception handler for i.e logging:

{rollback}

The {try} block can also be stopped and skipped manually using {rollback}. So you do not have to check all the input data in advance, and only during rendering you can decide whether it makes sense to render the object.

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

Variables

{var} {default}

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

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

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

The {default} tag works similarly, except that it creates variables only if they do not exist:

{default $lang = 'cs'}

You can also specify types of variables. 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 its beginning:

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

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

Other than the declared variables are not passed into the template. This is a difference from the {default} tag.

{capture}

By using {capture} tag you can capture the output to a variable:

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

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

The tag can also be written as n:attribute, like any pairwise tag:

<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 avoid unwanted escaping when printing.

Others

{contentType}

Use the tag to specify what 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-featured MIME type, such as application/xml, it also sends an HTTP header Content-Type 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 the place where code execution will break. It is used for debugging purposes for the programmer to inspect the runtime environment and to ensure the code runs as expected. It supports Xdebug. Additionally, you can specify a condition when the code should break.

{debugbreak}                {* breaks the program *}

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

{do}

Executes the PHP code and doesn't print anything. As with all other tags, PHP code is a single expression, see PHP limitations.

{do $num++}

{dump}

Dumps a variable or current context.

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

{dump}       {* dumps all the defined variables *}

Requires package Tracy.

{php}

Allows you to execute any PHP code. The tag must be activated using the RawPhpExtension extension.

{spaceless}

Removes unnecessary whitespace. It is similar to spaceless filter.

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

Outputs:

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

The tag can also be written as n:attribute:

{syntax}

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

  • double: {{...}}
  • off: completely disables Latte tags

By using the n:attribute notation we can disable Latte for a JavaScript block only:

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

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

If you turn off Latte with the {syntax off} (ie tag, not the n:attribute), it will strictly ignore all tags up to {/syntax}.

{trace}

Throws an Latte\RuntimeException exception, whose stack trace is in the spirit of the templates. Thus, instead of calling functions and methods, it involves calling blocks and inserting templates. If you use a tool for clearly displaying thrown exceptions, such as Tracy, you will clearly see the call stack, including all passed arguments.

HTML Tag Helpers

n:class

Thanks to n:class, it is very easy to generate the HTML attribute class exactly as you need.

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

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

And I further need that the first element 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 list-item class:

{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 displays eg:

<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, ie an element containing nothing but whitespace.

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

Depending on the values of the variable $error this will print:

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

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

Translation

To make the translation tags work, you need to set up 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}

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

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

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

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

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