Nette Documentation Preview

syntax
Syntax
******

.[perex]
Syntax Latte was born out of the practical requirements of web designers. We were looking for the most user-friendly syntax, with which you can elegantly write constructs that are otherwise a real challenge.
At the same time, all expressions are written exactly the same as in PHP, so you don't have to learn a new language. You just make the most of what you already know.

Below is a minimal template that illustrates a few basics elements: tags, n:attributes, comments and filters.

```latte
{* this is a comment *}
<ul n:if="$items">                {* n:if is n:attribute *}
{foreach $items as $item}         {* tag representing foreach loop *}
	<li>{$item|capitalize}</li>   {* tag that prints a variable with a filter *}
{/foreach}                        {* end of cycle *}
</ul>
```

Let's take a closer look at these important elements and how they can help you build an incredible template.


Tags
====

A template contains tags that control the template logic (for example, *foreach* loops) or output expressions. For both, a single delimiter `{ ... }` is used, so you don't have to think about which delimiter to use in which situation, as with other systems.
If the `{` character is followed by a quote or space, Latte doesn't consider it to be the beginning of a tag, so you can use JavaScript constructs, JSON, or CSS rules in your templates without any problems.

See [overview of all tags|tags]. In addition, you can also create [custom tags|extending-latte#tags].


Latte Understands PHP
=====================

You can use PHP expressions that you know well inside the tags:

- variables
- strings (including HEREDOC and NOWDOC), arrays, numbers, etc.
- [operators |https://www.php.net/manual/en/language.operators.php]
- function and method calls (which can be restricted by [sandbox])
- [match |https://www.php.net/manual/en/control-structures.match.php]
- [anonymous functions |https://www.php.net/manual/en/functions.arrow.php]
- [callbacks |https://www.php.net/manual/en/functions.first_class_callable_syntax.php]
- multi-line comments `/* ... */`
- etc...

In addition, Latte adds several [nice extensions |#Syntactic Sugar] to the PHP syntax.


n:attributes
============

Each pair tag, such as `{if} … {/if}`, operating upon single HTML element can be written in [n:attribute |#n:attribute] notation. For example, `{foreach}` in the above example could also be written this way:

```latte
<ul n:if="$items">
	<li n:foreach="$items as $item">{$item|capitalize}</li>
</ul>
```

The functionality then corresponds to the HTML element in which it is written:

```latte
{var $items = ['I', '♥', 'Latte']}

<p n:foreach="$items as $item">{$item}</p>
```

Prints:

```latte
<p>I</p>
<p>♥</p>
<p>Latte</p>
```

By using `inner-` prefix we can alter the behavior so that the functionality applies only to the body of the element:

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

Prints:

```latte
<div>
	<p>I</p>
	<hr>
	<p>♥</p>
	<hr>
	<p>Latte</p>
	<hr>
</div>
```

Or by using `tag-` prefix the functionality is applied on the HTML tags only:

```latte
<p><a href={$url} n:tag-if="$url">Title</a></p>
```

Depending on the value of `$url` variable this will print:

```latte
// when $url is empty
<p>Title</p>

// when $url equals 'https://nette.org'
<p><a href="https://nette.org">Title</a></p>
```

However, n:attributes are not only a shortcut for pair tags, there are some pure n:attributes as well, for example the coder's best friend [n:class|tags#n:class].


Filters
=======

See the summary of [standard filters|filters].

Latte allows calling filters by using the pipe sign notation (preceding space is allowed):

```latte
<h1>{$heading|upper}</h1>
```

Filters can be chained, in that case they apply in order from left to right:

```latte
<h1>{$heading|lower|capitalize}</h1>
```

Parameters are put after the filter name separated by colon or comma:

```latte
<h1>{$heading|truncate:20,''}</h1>
```

Filters can be applied on expression:

```latte
{var $name = ($title|upper) . ($subtitle|lower)}
```

On block:

```latte
<h1>{block |lower}{$heading}{/block}</h1>
```

Or directly on value (in combination with [`{=expr}`| https://latte.nette.org/en/tags#printing] tag):
```latte
<h1>{='  Hello world  '|trim}<h1>
```


Dynamic HTML Tags
=================

Latte supports dynamic HTML tags, which are useful when you need flexibility in tag names:

```latte
<h{$level}>Heading</h{$level}>
```

For example, the code above can generate `<h1>Heading</h1>` or `<h2>Heading</h2>` depending on the value of the variable `$level`. Dynamic HTML tags in Latte must always be paired. Their alternative is the [n:tag |tags#n:tag].

Because Latte is a secure templating system, it checks that the resulting tag name is valid and contains no unwanted or malicious values. It also ensures that the end tag name is always the same as the opening tag name.


Comments
========

Comments are written this way and do not get into the output:

```latte
{* this is a comment in Latte *}
```

PHP comments work inside tags:

```latte
{include 'file.info', /* value: 123 */}
```


Syntactic Sugar
===============


Strings Without Quotation Marks
-------------------------------

Quotation marks can be omitted for simple strings:

```latte
as in PHP:   {var $arr = ['hello', 'btn--default', '€']}

abbreviated: {var $arr = [hello, btn--default, €]}
```

Simple strings are those that are made up purely of letters, digits, underscores, hyphens and periods. They must not begin with a digit and must not begin or end with a hyphen.
It must not be composed of only uppercase letters and underscores, because then it is considered a constant (e.g. `PHP_VERSION`).
And it must not collide with the keywords `and`, `array`, `clone`, `default`, `false`, `in`, `instanceof`, `new`, `null`, `or`, `return`, `true`, `xor`.


Short Ternary Operator
----------------------

If the third value of the ternary operator is empty, it can be omitted:

```latte
as in PHP:   {$stock ? 'In stock' : ''}

abbreviated: {$stock ? 'In stock'}
```


Modern Key Notation in the Array
--------------------------------

Array keys can be written similarly to named parameters when calling functions:

```latte
as in PHP:   {var $arr = ['one' => 'item 1', 'two' => 'item 2']}

modern:      {var $arr = [one: 'item 1', two: 'item 2']}
```


Filters
-------

Filters can be used for any expression, just enclose the whole in brackets:

```latte
{var $content = ($text|truncate: 30|upper)}
```


Operator `in`
-------------

The `in` operator can be used to replace the `in_array()` function. The comparison is always strict:

```latte
{* like in_array($item, $items, true) *}
{if $item in $items}
	...
{/if}
```


A Window into History
---------------------

Latte has come up with a number of syntactic candies over the course of its history, which appeared in PHP itself a few years later. For example, in Latte it was possible to write arrays as `[1, 2, 3]` instead of `array(1, 2, 3)` or use the nullsafe operator `$obj?->foo` long before it was possible in PHP itself. Latte also introduced the array expansion operator `(expand) $arr`, which is the equivalent of today's `...$arr` operator from PHP.

The undefined-safe operator `??->`, which is similar to the nullsafe operator `?->`, but does not raise an error if the variable does not exist, was created for historical reasons and today we recommend using the standard PHP operator `?->`.


PHP Limitations in Latte
========================

Only PHP expressions can be written in Latte. That is, statements ending with a semicolon cannot be used. You cannot declare classes or use [control structures |https://www.php.net/manual/en/language.control-structures.php], such as `if`, `foreach`, `switch`, `return`, `try`, `throw` and others, instead of which Latte offers its [tags].
You also can't use [attributes |https://www.php.net/manual/en/language.attributes.php], [backticks |https://www.php.net/manual/en/language.operators.execution.php] or any of [magic constants |https://www.php.net/manual/en/language.constants.magic.php].
You can't even use `unset`, `echo`, `include`, `require`, `exit`, `eval`, because they are not functions, but special PHP language constructs, and thus not expressions. Only multi-line comments are supported `/* ... */`.

However, you can work around these limitations by activating the [RawPhpExtension |develop#RawPhpExtension] extension, which allows you to use any PHP code in the `{php ...}` tag at the responsibility of the template author.

Syntax

Syntax Latte was born out of the practical requirements of web designers. We were looking for the most user-friendly syntax, with which you can elegantly write constructs that are otherwise a real challenge. At the same time, all expressions are written exactly the same as in PHP, so you don't have to learn a new language. You just make the most of what you already know.

Below is a minimal template that illustrates a few basics elements: tags, n:attributes, comments and filters.

{* this is a comment *}
<ul n:if="$items">                {* n:if is n:attribute *}
{foreach $items as $item}         {* tag representing foreach loop *}
	<li>{$item|capitalize}</li>   {* tag that prints a variable with a filter *}
{/foreach}                        {* end of cycle *}
</ul>

Let's take a closer look at these important elements and how they can help you build an incredible template.

Tags

A template contains tags that control the template logic (for example, foreach loops) or output expressions. For both, a single delimiter { ... } is used, so you don't have to think about which delimiter to use in which situation, as with other systems. If the { character is followed by a quote or space, Latte doesn't consider it to be the beginning of a tag, so you can use JavaScript constructs, JSON, or CSS rules in your templates without any problems.

See overview of all tags. In addition, you can also create custom tags.

Latte Understands PHP

You can use PHP expressions that you know well inside the tags:

In addition, Latte adds several nice extensions to the PHP syntax.

n:attributes

Each pair tag, such as {if} … {/if}, operating upon single HTML element can be written in n:attribute notation. For example, {foreach} in the above example could also be written this way:

<ul n:if="$items">
	<li n:foreach="$items as $item">{$item|capitalize}</li>
</ul>

The functionality then corresponds to the HTML element in which it is written:

{var $items = ['I', '♥', 'Latte']}

<p n:foreach="$items as $item">{$item}</p>

Prints:

<p>I</p>
<p>♥</p>
<p>Latte</p>

By using inner- prefix we can alter the behavior so that the functionality applies only to the body of the element:

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

Prints:

<div>
	<p>I</p>
	<hr>
	<p>♥</p>
	<hr>
	<p>Latte</p>
	<hr>
</div>

Or by using tag- prefix the functionality is applied on the HTML tags only:

<p><a href={$url} n:tag-if="$url">Title</a></p>

Depending on the value of $url variable this will print:

// when $url is empty
<p>Title</p>

// when $url equals 'https://nette.org'
<p><a href="https://nette.org">Title</a></p>

However, n:attributes are not only a shortcut for pair tags, there are some pure n:attributes as well, for example the coder's best friend n:class.

Filters

See the summary of standard filters.

Latte allows calling filters by using the pipe sign notation (preceding space is allowed):

<h1>{$heading|upper}</h1>

Filters can be chained, in that case they apply in order from left to right:

<h1>{$heading|lower|capitalize}</h1>

Parameters are put after the filter name separated by colon or comma:

<h1>{$heading|truncate:20,''}</h1>

Filters can be applied on expression:

{var $name = ($title|upper) . ($subtitle|lower)}

On block:

<h1>{block |lower}{$heading}{/block}</h1>

Or directly on value (in combination with {=expr} tag):

<h1>{='  Hello world  '|trim}<h1>

Dynamic HTML Tags

Latte supports dynamic HTML tags, which are useful when you need flexibility in tag names:

<h{$level}>Heading</h{$level}>

For example, the code above can generate <h1>Heading</h1> or <h2>Heading</h2> depending on the value of the variable $level. Dynamic HTML tags in Latte must always be paired. Their alternative is the n:tag.

Because Latte is a secure templating system, it checks that the resulting tag name is valid and contains no unwanted or malicious values. It also ensures that the end tag name is always the same as the opening tag name.

Comments

Comments are written this way and do not get into the output:

{* this is a comment in Latte *}

PHP comments work inside tags:

{include 'file.info', /* value: 123 */}

Syntactic Sugar

Strings Without Quotation Marks

Quotation marks can be omitted for simple strings:

as in PHP:   {var $arr = ['hello', 'btn--default', '€']}

abbreviated: {var $arr = [hello, btn--default, €]}

Simple strings are those that are made up purely of letters, digits, underscores, hyphens and periods. They must not begin with a digit and must not begin or end with a hyphen. It must not be composed of only uppercase letters and underscores, because then it is considered a constant (e.g. PHP_VERSION). And it must not collide with the keywords and, array, clone, default, false, in, instanceof, new, null, or, return, true, xor.

Short Ternary Operator

If the third value of the ternary operator is empty, it can be omitted:

as in PHP:   {$stock ? 'In stock' : ''}

abbreviated: {$stock ? 'In stock'}

Modern Key Notation in the Array

Array keys can be written similarly to named parameters when calling functions:

as in PHP:   {var $arr = ['one' => 'item 1', 'two' => 'item 2']}

modern:      {var $arr = [one: 'item 1', two: 'item 2']}

Filters

Filters can be used for any expression, just enclose the whole in brackets:

{var $content = ($text|truncate: 30|upper)}

Operator in

The in operator can be used to replace the in_array() function. The comparison is always strict:

{* like in_array($item, $items, true) *}
{if $item in $items}
	...
{/if}

A Window into History

Latte has come up with a number of syntactic candies over the course of its history, which appeared in PHP itself a few years later. For example, in Latte it was possible to write arrays as [1, 2, 3] instead of array(1, 2, 3) or use the nullsafe operator $obj?->foo long before it was possible in PHP itself. Latte also introduced the array expansion operator (expand) $arr, which is the equivalent of today's ...$arr operator from PHP.

The undefined-safe operator ??->, which is similar to the nullsafe operator ?->, but does not raise an error if the variable does not exist, was created for historical reasons and today we recommend using the standard PHP operator ?->.

PHP Limitations in Latte

Only PHP expressions can be written in Latte. That is, statements ending with a semicolon cannot be used. You cannot declare classes or use control structures, such as if, foreach, switch, return, try, throw and others, instead of which Latte offers its tags. You also can't use attributes, backticks or any of magic constants. You can't even use unset, echo, include, require, exit, eval, because they are not functions, but special PHP language constructs, and thus not expressions. Only multi-line comments are supported /* ... */.

However, you can work around these limitations by activating the RawPhpExtension extension, which allows you to use any PHP code in the {php ...} tag at the responsibility of the template author.