Nette Documentation Preview

Latte Tags

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

Variable and expression printing
{$variable} prints an escaped variable
{$variable|noescape} prints a variable without escaping
{expression} prints an escaped expression
{=expression} prints an escaped expression
{if $cond} … {elseif $cond} … {else} … {/if} if condition
{$cond ? $value1 : $value2} ternary operator
{$cond ? $value} abbreviated „ternary“ operator
{$a ?: $default} prints $a, if is empty prints $default
{ifset $var} … {elseifset $var} … {/ifset} if (isset()) condition
{switch $var} … {case value} … {default} … {/switch} choice by value
{$obj?->prop} {$arr?['item']} forms of optional chaining
{foreach $arr as $item} … {/foreach} foreach loop
{for expr; expr; expr} … {/for} for loop
{while expr} … {/while} while loop
{continueIf $cond} conditional jump to the next iteration
{breakIf $cond} conditional loop break
{first} … {/first} prints if first iteration
{last} … {/last} prints if last iteration
{sep} … {/sep} separator
{var $foo = value} variable creation
{default $foo = value} default value when variable isn't declared
{capture $var} … {/capture} captures a section to a variable
Blocks, layouts, template inheritance
{block block} block definition and immediate print out
{define block} block defintion for future use
{include block} inserts a block
{include 'file.latte'} includes a template from other file
{import 'file.latte'} loads blocks from external template
{layout 'file.latte'} specifies a layout file
{extends 'file.latte'} alias for {layout}
{ifset #block} … {/ifset} condition if block is defined
{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
{sandbox 'file.latte'} includes a template in sandbox mode
{do expression} evaluates an expression without printing it
{* comment text *} a comment (removed from evaluation)
{l} or {r} prints { and } characters, respectively
{syntax mode} switches the syntax at runtime
{spaceless} … {/spaceless} removes unnecessary whitespace, similar to strip filter
{contentType $type} switches the escaping mode and sends HTTP header
{debugbreak $cond} sets breakpoint to the code
HTML tag attributes
n:class smart class attribute
n:attr smart HTML attributes
n:ifcontent Omit empty HTML tag
n:tag-if Omit HTML tag if condition is false
(expand) expansion of arrays
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
Controls and forms
{control loginForm} prints a component
{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
{snippet name} … {/snippet} a template snippet that can be sent by AJAX
{snippetArea name} snippets envelope
{_}Text{/_} translates a text
{_expression} translates an expression and prints it with escaping
{dump $variable} dumps variables to the Tracy Bar
{cache $key} … {/cache} caches a template section

Variable and expression printing {expression}

With escaping: (eliminates the Cross Site Scripting vulnerability):

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

Without escaping by using the |noescape modifier (an exclamation mark was used in older Nette versions):

<div class="article">

Alternatively you can use notations with equals sign {=expression}. This is useful in cases where it may not be obvious that the expression is actually an expression and not a tag or JSON:

Version: {=PHP_VERSION}
Name: {="string"}

With technology of Context-Aware Escaping it is also possible to use PHP variables inside the JavaScript safely:

var arr = {$arr};
var name = {$name}; // quotes are automatically added!

Conditions {if $cond} … {/if}, {$cond ? … : …}

Conditions behave exactly the same way as their PHP counterparts:

{if $stock}
	In stock
{elseif $onWay}
	On the way
	Not available

You can also use {ifset} tag which checks variable existence and corresponds to the if (isset($var)) PHP code. {ifset} tag can check for block existence as well.

Expression in the {if} condition can be placed in the closing tag which is useful in situations when we don't know the expression at the time of opening the condition block:

	<h1>Printing rows from the database</h1>

	{foreach $database->table as $row} ... {/foreach}
{/if $row}

Block {if} with condition in a closing tag does not support {elseif}, tag {else} can be used.

availability: {$stock ? 'In stock' : 'Not in stock'}

shortly: {$stock ? 'In stock'}

Repetitive expression in condition could be shortened by {switch} and {case} tags. Those are expanded to series of if ($var === 'value') conditions, i.e. works differently than PHP. break is omitted.

{switch $transport}
	{case train}
		By train
	{case plane}
		By plane

Optional Chaining

Optional chaining lets us write code where Latte immediately stops evaluating expressions if it encounters null. With the new ? operator allowing optional access to variables or array elements. When we write code like


this is a way of saying that when $order is defined, $order->id will be computed, but when $order is null, stop what we’re doing and just return null.

You might find yourself using ? to replace a lot of code that performs repetitive nullish checks:

// roughly means isset($user) && isset($user->address) ? $user->address->street : null

// roughly means isset($items[2]) ? $items[2]->count : null

// roughly means $user->getIdentity() !== null ? $user->getIdentity()->name : null

The meaning are „roughly“ because in fact the expression is evaluated more sophistically and no step is repeated. For example, $user->getIdentity() is called only once, so there cannot be a problem due to an object being returned in the condition and then null.

Optional chaining expressions can be used anywhere, for example, in terms of:

{if $blogPost?->count('*')}
	// means if (isset($blogPost) && $blogPost->count('*'))

Loops {foreach}, {for}, {while}

foreach, for and while loops behave exactly the same as their PHP counterparts.

{foreach $result as $row}
{while $row = $result->fetch()}
{for $i = 0; $i < 10; $i++}
	<span>Item #{$i}</span>

Inside the foreach loop the $iterator variable is initialized. It holds important information about the current loop. Its API features iteration counter and methods identifying odd, even, first and last iteration:

  • isFirst() – is this the first iteration?
  • isLast() – is this the last iteration?
  • getCounter() – iteration counter, starts from 1
  • isOdd() – is this iteration odd?
  • isEven() – is this iteration even?

Object behind the $iterator variable has Nette\SmartObject trait characteristics, that's why you can write $iterator->first instead of $iterator->isFirst() and alike. For example:

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

	<tr id="row-{$iterator->counter}">

	{if $iterator->last}</table>{/if}

{if $iterator->first}<table>{/if} can be replaced with {first}<table>{/first}. Similarly, the condition with last can be also written as {last}</table>{/last}.

{foreach $rows as $row}
		{first 5}<tr>{/first} {* new row each 5 items *}
		{last 5}</tr>{/last}

Finally, the equivalent of {if !$iterator->last} … {/if} notation (ie. not the last item) is {sep} … {/sep} tag. Usually it marks the separator between items – comma, for example. This way the redundant right comma won't print:

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

There are two special tags you can use inside the 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->parent == null}

The cycle definition can be merged with the HTML definition as follows: (lists the div element for each row)

<div n:foreach="$rows as $row">

Or, use the inner loop to repeat only the inside of the element: (ul is displayed once, li for each line)

<ul n:inner-foreach="$rows as $row">

Variable declaration {var} and {default}

We can declare variables directly in the template by using {var} tag:

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

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

Tag {default} does the same thing, except it only sets the value to nonexistent variables:

{default $lang = 'cs'}

As of Latte 2.7, you can declare the type of variables:

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

Capturing to variables {capture}

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

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

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

If you want to capture the output only for a filter to be applied it is easier to use the filter on the {block} instead:

	<li>Hello World</li>

File including {include} and {sandbox}

You can include other templates into the current template. The included file has access to the global variables of the current template. Additionally, we can also pass other variables listed in the tag:

{include 'basket.latte'}

{include 'menu.latte', level => 3, data => $menu}

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

The file can also be inserted in safe sandbox mode. In this case, the included file does have access to only those variables that you explicitly pass:

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

Code evaluation {do expression}

Evaluates the code written inside but it doesn't print it. (As of Latte 2.8, {php} works in older versions).

Header {contentType}

Switches Context-Aware Escaping to the context determined by the parameter so that when printing, the variables are escaped using the rules of the context. For example {contentType xml} would switch to the XML escaping mode, meanwhile {contentType text} disables escaping completely.

If the parameter is a complete MIME type the correct HTTP header is sent to the browser:

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

Breakpoint {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 and PhpEd. 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 *}

Syntax switching {syntax}

Tags don't have to be enclosed by simple braces only, we can also use other delimiters, even at runtime. That's the function of {syntax …} tag where we can use the following parameters:

  • latte: {...}
  • double: {{...}}
  • off: completely disables tag evaluation

Note: asp and python syntaxes were removed in 2.4.0.

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

Latte mode can easily be used in JavaScript, you just have to avoid the notation above by writing a space after the opening brace { var: 123} or by using quotes around the identifier {'var': 123}.

If you turn off Latte with {syntax off} (using tag, not n:attribute), remember that you can not turn it back on using {syntax}. No parentheses are processed, so neither the syntax exception termination tag.


In a typical situation, we could be trying to print an unknown amount of entries from the database as <li> elements and mark the last entry and every odd item with corresponding CSS classes for further styling. In case the last line is odd as well, we will require both classes, but we want to avoid empty classes like <li class=" ">.

By using n:class attribute the problem is rather trivial:

	{foreach $data as $item}
	<li n:class="$iterator->odd ? alt, $iterator->last ? last">{$item}</li>

Or do you need to mark the current menu link with ‚current‘ class?

<a href="#" n:class="$presenter->isLinkCurrent('Presenter:*') ? current">

Amazing, huh?

If you need more accurate URL detection, the isLinkCurrent() method can also pass the expected parameter

<a href="#" n:class="$presenter->isLinkCurrent('Presenter:action', 'slug') ? current">


n:attr attribute is able to generate any HTML attribute similarly to the n:class. It's mostly suitable in cases when we don't know which attributes we want to print and which not to.

<input type="checkbox" n:attr="value => $value, checked => $checked">

Depending on the values of the variables $value and $checked this will print:

<input type="checkbox">

{* $value = 'Hello' *}
<input type="checkbox" value="Hello">

{* $checked = true *}
<input type="checkbox" value="Hello" checked>


n:ifcontent removes empty tag

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

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

{* $error = '' *}

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

Blocks {block} and {define}

Block selects a region of the template, for example to apply a filter (see example) or to name it and reinsert it elsewhere in the template.

{block sidebar}

We can nest the blocks and of course we can write them in n:attribute notation:

{block sidebar}

	<ul n:block="menulist">

A block is immediately printed. In case we want to define the block only without printing it we can use {define} instead of {block}. In addition, it can receive parameters:

{define card, $name, $collapsed}

{include card, $person->name, true}

As of Latte 2.7, parameter types can also be declared: {define sidebar, string $name, bool $mode}.

As for the name of the block it is allowed to specify it by a variable too: {block $var} … {/block}.

Every block can see the variables of its surroundings. But alternation of the value inside the block will be visible only in the block (and in nested blocks of course).

The existence of a block can by tested with {ifset #block}.

Block and template inclusion {include block} or {include 'mytemplate.latte'}

Block and template inclusion is performed using {include}.

{include sidebar}

Analogically for templates:

{include 'sidebar.latte'}

It is also possible to pass additional parameters:

{include sidebar, id => 123, name => $value}

We can include a block by specifying the block name stored in a variable as well (to differentiate from including a file we use the hash sign before the block name):

{include #$blockname}

Blocks can also include themselves which is suitable when rendering a tree structured menu.

{block menu}
	{foreach $menu as $item}
	<li>{if is_array($item)}
		{include menu, menu => $item}

Instead of {include menu, ...} we can write {include this, ...} where #this points to the current block.

If you need to add some code to the previously defined block (e.g. add a link to a new stylesheet), you don't need to redeclare and copy the whole block. Use {include parent} instead.

{block styles}
	{include parent}
	<link href="" rel="stylesheet">

Template expansion/inheritance {layout}

Template expansion (also called inheritance) is a powerful tool which enables us to create even very complicated layouts effectively and with no code repetition.

Let's say we have two simple pages. The first one:

		<title>First page | My web</title>
		<div id="sidebar">

		<div id="content">
			<p>Lorem Gypsum...</p>

and the second:

		<title>Second page | My web</title>
		<div id="sidebar">

		<div id="content">
			<p>Proin eu sem purus. Donec bibendum

The pages vary only by <title> and <div#content> elements, so we'll create a layout file which contains all common parts and specifies placeholders, which are nothing more but blocks:

File @layout.latte:

		<title>{block title}{/block} | My web</title>
		<div id="sidebar">

		<div id="content">{block content}{/block}</div>

In the actual templates we'll point to the layout by using the {layout}, so we can minimize the template content by only defining the two blocks:

{layout '@layout.latte'}

{block title}First page{/block}

{block content}<p>Lorem Gypsum...</p>{/block}

The other page will look similar.

Also, there are no limits to the number of levels, there can be as many layers as you want.

Typed templates {varType}, {varPrint}, {templateType}{templatePrint}

Type system is main thing for the development of robust applications. To knowing what data or object type each variable is allows IDE to correctly autocomplete (see Typed Templates).

How to declare types? Use tags {varType} or {var} to define the types of individual variables directly in the template:

{varType Nette\Security\User $user}
{varType string $lang}

The {varPrint} tag saves you time. If you place it in a template, the list of {varType} tags is displayed instead of the normal rendering. Then simply select and copy the code into your template. The {varPrint} lists local variables that are not template parameters. If you want to list all variables, use {varPrint all}.

The types of parameters passed to the template can be declared using class, which we state at the beginning of the template:

{templateType MyApp\CatalogTemplate}

You can also generate this class using the {templatePrint} tag. If you place it at the beginning of the template, the code of class is displayed instead of the normal template. Then simply select and copy the code into your project.

Component rendering {control …}

{control} renders the presenter component. For better understanding it's good to know how the tag is compiled to PHP code.

{control cartControl}		renders whole cart on the page
{control cartControl:small}	renders small sidebar cart summary

This compiles to:


getComponent() method returns the cartControl component and then the render() or renderSmall() method, respectively, is called on it.

We can also add parameters which will be passed to the render method, for example:

{control cartControl, $maxItems, $showSummary}
{control cartControl, maxItems => 5, showSummary => true}
{control cartControl, [maxItems => 5, showSummary => true]}
{control cartControl:small, $maxItems, $showSummary}

compiles to:

$control->getComponent('cartControl')->render($maxItems, $showSummary);
$control->getComponent('cartControl')->render(['maxItems' => 5, 'showSummary' => true]);
$control->getComponent('cartControl')->render([['maxItems' => 5, 'showSummary' => true]]);
$control->getComponent('cartControl')->renderSmall($maxItems, $showSummary);

If anywhere in the parameter part => is used, all parameters will be wrapped with an array and passed as the first argument.

Rendering of sub-component:

{control cartControl-someForm}

compiles to:


Forms {form}, {input}, {inputError}{label}

Tags for rendering forms and their elements:

{form myForm}
<tr n:foreach="$form->controls as $name => $field">
	<th>{label $name /}<th>
	<td>{input $name}</td>
	<td n:ifcontent>{inputError $name}</td>

The {form} or <form n:name> tag starts rendering of given form. It also creates a local variable $form with a form object. The closing {/form} or </form> tag renders all undrawn hidden fields before completes the form.

{input} tag renders any element including select boxes and textareas. {label} is optionally paired tag, ie. {label}Age{/label}, in that case the text is translated too. Tag {inputError} prints error message for form input.

It's also possible to „breathe life“ into a raw HTML input with n:name attribute tag, which links it with the form input using its identification:

<form n:name=myForm>
	<p>Name: <input size="50" n:name="name"></p>
	<p>Password: <input size="30" n:name="password"></p>

You can also generate Latte code for a form using the {formPrint} tag. If you place it in a template, the code of form is displayed instead of the normal template. Then simply select and copy the code into your project. (since nette/forms 3.0.5)

If you only need to render the inner content of a form without <form> & </form> HTML tags, for example, in an AJAX request, you can open and close the form with {formContext formName} … {/formContext}. It works similarly to {form} in a logical sense, here it allows you to use other tags to draw form elements, but at the same time it doesn't draw anything. (since nette/forms 3.0.6)

Localization {_expression}

Tag which helps with automated translating in templates. For proper functionality a translator has to be set, see localization:

$latte->addFilter('translate', new MyTranslator);

At this point every expression written in this tag will be automatically translated:


You can also use an alternative pair notation for chunks of text within a template:

{_}Text to be translated{/_}

Variable dumping {dump}

Requires Tracy.

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

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

Array expansion operator (expand)

The (expand) operator allows you to use an array where multiple arguments are expected. This is the equivalent of the ... operator from PHP, but retaining the keys.

It can be used, for example, to pass arguments into blocks or included templates if we have them in the array.

{include 'foobar.latte' (expand) $args}          {* arguments for include *}