Latte Tags

Summary and description of all Latte built-in tags (also called macros).

Printing
{$var}, {expr} or {=expr} prints an escaped variable or expression
{$var|filter} prints with filters
{_string} prints translated
{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
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
{first}{/first} is it the first iteration?
{last}{/last} is it the last iteration?
{sep}{/sep} will next iteration follow?
$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 block} block definition
{define block} block defintion for future use
{include block} prints block
{import 'file.latte'} loads blocks from another template
{layout 'file.latte'} / {extends} specifies a layout file
{embed 'file.latte'} loads the template and allows you to overwrite the blocks
{ifset block}{/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
{capture $var}{/capture} captures a section to a variable
Types
{varType type $var} declares type of variable
{varPrint [all]} suggests types of variables
{templateType ClassName} declares types of variables using class
{templatePrint} generates class with properties
Others
{contentType $type} switches the escaping mode and sends HTTP header
{debugbreak $cond} sets breakpoint to the code
{do expression} evaluates an expression without printing it
{dump $variable} dumps variables to the Tracy Bar
{spaceless}{/spaceless} removes unnecessary whitespace
{syntax mode} switches the syntax at runtime
HTML tag helpers
n:class smart class attribute
n:attr smart HTML attributes
n:ifcontent Omit empty HTML tag
Available only in Nette Framework
n:href link in <a> HTML elements
{link Presenter:action} generates a link
{plink Presenter:action} generates a link to a presenter
{control loginForm} prints a component
{snippet name}{/snippet} a template snippet that can be sent by AJAX
{snippetArea name} snippets envelope
{cache $key}{/cache} caches a template section
Available only with Nette Forms
{form formName}{/form} prints a form element
{label fieldName}{/label} prints a form input label
{input fieldName} prints a form input element
{inputError fieldName} prints error message for form input element
n:name activates an HTML input element
{formPrint} generates Latte form blueprint
{formContext formName}{/formContext} partial form rendering

Vypisování

{$var} {expr} {=expr}

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 write 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 verified source? Then you can easily turn off escaping:

{$trustedHtmlString|noescape}

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}

{_string}

If you use Nette, we will refer you to the chapter localization.

The tag facilitates automated translations in templates. Internally, it uses a filter called translate, so both of these entries work the same:

{_$variable}
{$variable|translate}

You are expected to initialize the filter. There is a wide range of libraries that handle string translation and can be integrated to Latte as follows:

$latte->addFilter('translate', function ($original) {
	// here we somehow create $translated from $original
	return $translated;
});

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.

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

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

In addition to checking the existence of variables, {ifset} is also used to verify block existence.

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

{foreach $rows as $row}
	{first}<table>{/first}

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

	{last}</table>{/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?

{for}

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

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

{while}

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

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

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>

Including Templates

{include}

The {include} tag tells Latte to print the specified template. In our favorite PHP language it's like:

<?php include('file.php'); ?>

In addition to including templates the {include} tag is also used to include blocks.

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

You can pass variables this way:

{* since Latte 2.9 *}
{include 'template.latte', foo: 'bar', id: 123}

{* before Latte 2.9 *}
{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 (since Latte 2.9.1):

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

Named blocks are the basic building block for inheritance and reusability of templates. However, a 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}

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

As of Latte 2.7, you can also specify types of variables.

{var string $name = $article->getTitle()}

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

Others

{contentType}

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

  • html (default type)
  • xhtml
  • 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 code and does not print anything.

{do $num++}

In Latte 2.7 and earlier, the {php} was used.

{dump}

Dumps a variable or current context. Requires Tracy.

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

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

{spaceless}

Removes unnecessary whitespace. It is similar to strip filter.

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

Outputs:

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

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

  • latte: {...}
  • 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 {. Either by inserting a space or line break between them ({ var: 123}) or by using quotation marks around the key ({'var': 123}).

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

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 class first:

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

And all elements should have the main-item class:

{foreach $items as $item}
	<a n:class="$item->isActive() ? active, $iterator->first ? first, main-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: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>
Improve this page