Latte Filters
In templates, we can use functions that help modify or reformat data into its final form. We call them filters.
capitalize |
lowercase, first letter of each word uppercase |
firstUpper |
converts the first letter to uppercase |
lower |
converts to lowercase |
upper |
converts to uppercase |
ceil |
rounds a number up to a given precision |
floor |
rounds a number down to a given precision |
round |
rounds a number to a given precision |
escapeUrl |
escapes a parameter in a URL |
noescape |
outputs a variable without escaping |
query |
generates a query string in a URL |
There are also escaping filters for HTML (escapeHtml
and escapeHtmlComment
), XML
(escapeXml
), JavaScript (escapeJs
), CSS (escapeCss
) and iCalendar
(escapeICal
), which Latte uses itself thanks to context-aware escaping and you do not need to
write them.
checkUrl |
sanitizes a URL address from dangerous inputs |
nocheck |
prevents automatic URL sanitization |
Latte the src
and href
attributes checks automatically, so you almost don't need to use the
checkUrl
filter.
All built-in filters are designed for strings in UTF‑8 encoding.
Usage
Filters are written after the pipe symbol (a space before it is allowed):
<h1>{$heading|upper}</h1>
Filters can be chained, and they are applied in order from left to right:
<h1>{$heading|lower|capitalize}</h1>
Parameters are entered after the filter name, separated by colons or commas:
<h1>{$heading|truncate:20,''}</h1>
Filters can also be applied to an expression:
{var $name = ($title|upper) . ($subtitle|lower)}</h1>
Custom filters can be registered this way:
$latte = new Latte\Engine;
$latte->addFilter('shortify', fn(string $s, int $len = 10) => mb_substr($s, 0, $len));
It is then called in the template like this:
<p>{$text|shortify}</p>
<p>{$text|shortify:100}</p>
Filters
batch (int $length, mixed $item): array
A filter that simplifies listing linear data in a table format. It returns an array of arrays with the specified number of items. If you provide a second parameter, it will be used to fill in missing items in the last row.
{var $items = ['a', 'b', 'c', 'd', 'e']}
<table>
{foreach ($items|batch: 3, 'No item') as $row}
<tr>
{foreach $row as $column}
<td>{$column}</td>
{/foreach}
</tr>
{/foreach}
</table>
Outputs:
<table>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
</tr>
<tr>
<td>d</td>
<td>e</td>
<td>No item</td>
</tr>
</table>
See also group and the iterateWhile tag.
breakLines
Inserts an HTML <br>
tag before each newline character.
{var $s = "Text & with \n newline"}
{$s|breakLines} {* outputs "Text & with <br>\n newline" *}
bytes (int $precision=2)
Formats the size in bytes into a human-readable form. If the locale is set, the corresponding decimal and thousand separators are used.
{$size|bytes} {* 0 B, 1.25 GB, … *}
{$size|bytes:0} {* 10 B, 1 GB, … *}
ceil (int $precision=0)
Rounds a number up to the given precision.
{=3.4|ceil} {* outputs 4 *}
{=135.22|ceil:1} {* outputs 135.3 *}
{=135.22|ceil:3} {* outputs 135.22 *}
capitalize
Words will start with uppercase letters, all remaining characters will be lowercase. Requires the mbstring
PHP
extension.
{='i like LATTE'|capitalize} {* outputs 'I Like Latte' *}
See also firstUpper, lower, upper.
checkUrl
Enforces URL sanitization. It checks if the variable contains a web URL (i.e., HTTP/HTTPS protocol) and prevents the output of links that could pose a security risk.
{var $link = 'javascript:window.close()'}
<a data-href={$link|checkUrl}>checked</a>
<a data-href={$link}>unchecked</a>
Outputs:
<a data-href="">checked</a>
<a data-href="javascript:window.close()">unchecked</a>
See also nocheck.
clamp (int|float $min, int|float $max)
Clamps a value to the given inclusive range of min and max.
{$level|clamp: 0, 255}
Also exists as a function.
dataStream (string
$mimetype='detect'
)
Converts content to the data URI scheme. This allows embedding images into HTML or CSS without needing to link external files.
Let's have an image in the variable $img = Image::fromFile('image.gif')
, then
<img src={$img|dataStream}>
Outputs, for example:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==">
Requires the fileinfo
PHP extension.
date (string $format)
Formats a date and time according to the mask used by the PHP function date. The filter
accepts the date as a UNIX timestamp, a string, or a DateTimeInterface
object.
{$today|date:'j. n. Y'}
See also localDate.
escapeUrl
Escapes a variable for use as a parameter in a URL.
<a href="http://example.com/{$name|escapeUrl}">{$name}</a>
See also query.
explode (string
$separator=''
)
Splits a string into an array by a delimiter. Alias for split
.
{='one,two,three'|explode:','} {* returns ['one', 'two', 'three'] *}
If the delimiter is an empty string (the default value), the input will be split into individual characters:
{='123'|explode} {* returns ['1', '2', '3'] *}
You can also use the alias split
:
{='1,2,3'|split:','} {* returns ['1', '2', '3'] *}
See also implode.
first
Returns the first element of an array or the first character of a string:
{=[1, 2, 3, 4]|first} {* outputs 1 *}
{='abcd'|first} {* outputs 'a' *}
floor (int $precision=0)
Rounds a number down to the given precision.
{=3.5|floor} {* outputs 3 *}
{=135.79|floor:1} {* outputs 135.7 *}
{=135.79|floor:3} {* outputs 135.79 *}
firstUpper
Converts the first letter to uppercase. Requires the mbstring
PHP extension.
{='the latte'|firstUpper} {* outputs 'The latte' *}
See also capitalize, lower, upper.
group (string|int|\Closure $by): array
The filter groups data according to various criteria.
In this example, rows in the table are grouped by the categoryId
column. The output is an array of arrays, where
the key is the value in the categoryId
column. Read the
detailed guide.
{foreach ($items|group: categoryId) as $categoryId => $categoryItems}
<ul>
{foreach $categoryItems as $item}
<li>{$item->name}</li>
{/foreach}
</ul>
{/foreach}
See also batch, the group function, and the iterateWhile tag.
implode (string $glue=''
)
Returns a string which is the concatenation of the items in the sequence. Alias for join
.
{=[1, 2, 3]|implode} {* outputs '123' *}
{=[1, 2, 3]|implode:'|'} {* outputs '1|2|3' *}
You can also use the alias join
:
{=[1, 2, 3]|join} {* outputs '123' *}
indent (int $level=1, string
$char="\t"
)
Indents text from the left by a given number of tabs or other characters specified in the second argument. Blank lines are not indented.
<div>
{block |indent}
<p>Hello</p>
{/block}
</div>
Outputs:
<div>
<p>Hello</p>
</div>
last
Returns the last element of an array or the last character of a string:
{=[1, 2, 3, 4]|last} {* outputs 4 *}
{='abcd'|last} {* outputs 'd' *}
length
Returns the length of a string or array.
- for strings, it returns the length in UTF‑8 characters
- for arrays, it returns the number of items
- for objects implementing the Countable interface, it uses the return value of the
count()
method - for objects implementing the IteratorAggregate interface, it uses the return value of the
iterator_count()
function
{if ($users|length) > 10}
...
{/if}
localDate (?string $format=null, ?string $date=null, ?string $time=null)
Formats date and time according to the locale, ensuring consistent
and localized display of time data across different languages and regions. The filter accepts the date as a UNIX timestamp,
string, or DateTimeInterface
object.
{$date|localDate} {* 15. dubna 2024 *}
{$date|format: yM} {* 4/2024 *}
{$date|localDate: date: medium} {* 15. 4. 2024 *}
If you use the filter without parameters, it will output the date at the long
level, see below.
a) Using format
The format
parameter describes which time components should be displayed. It uses letter codes, where the number
of repetitions affects the width of the output:
Year | y / yy / yyyy |
2024 / 24 / 2024 |
Month | M / MM / MMM / MMMM |
8 / 08 / Aug / August |
Day | d / dd / E / EEEE |
1 / 01 / Sun / Sunday |
Hour | j / H / h |
preferred / 24-hour / 12-hour |
Minute | m / mm |
5 / 05 (2 digits when combined with seconds) |
Second | s / ss |
8 / 08 (2 digits when combined with minutes) |
The order of codes in the format does not matter, as the order of components will be displayed according to the
locale's conventions. Thus, the format is locale-independent. For example, the format yyyyMMMMd
in the
en_US
locale outputs April 15, 2024
, while in the cs_CZ
locale it outputs
15. dubna 2024
:
locale: | cs_CZ | en_US |
---|---|---|
format: 'dMy' |
10. 8. 2024 | 8/10/2024 |
format: 'yM' |
8/2024 | 8/2024 |
format: 'yyyyMMMM' |
srpen 2024 | August 2024 |
format: 'MMMM' |
srpen | August |
format: 'jm' |
17:22 | 5:22 PM |
format: 'Hm' |
17:22 | 17:22 |
format: 'hm' |
5:22 odp. | 5:22 PM |
b) Using preset styles
The date
and time
parameters determine how detailed the date and time should be displayed. You can
choose from several levels: full
, long
, medium
, short
. You can choose to
display only the date, only the time, or both:
locale: | cs_CZ | en_US |
---|---|---|
date: short |
23.01.78 | 1/23/78 |
date: medium |
23. 1. 1978 | Jan 23, 1978 |
date: long |
23. ledna 1978 | January 23, 1978 |
date: full |
pondělí 23. ledna 1978 | Monday, January 23, 1978 |
time: short |
8:30 | 8:30 AM |
time: medium |
8:30:59 | 8:30:59 AM |
time: long |
8:30:59 SEČ | 8:30:59 AM GMT+1 |
date: short, time: short |
23.01.78 8:30 | 1/23/78, 8:30 AM |
date: medium, time: short |
23. 1. 1978 8:30 | Jan 23, 1978, 8:30 AM |
date: long, time: short |
23. ledna 1978 v 8:30 | January 23, 1978 at 8:30 AM |
For the date, you can also use the prefix relative-
(e.g., relative-short
), which for dates close to
the present will display yesterday
, today
, or tomorrow
; otherwise, it will display in the
standard way.
{$date|localDate: date: relative-short} {* yesterday *}
See also date.
lower
Converts a string to lowercase. Requires the mbstring
PHP extension.
{='LATTE'|lower} {* outputs 'latte' *}
See also capitalize, firstUpper, upper.
nocheck
Prevents automatic URL sanitization. Latte automatically checks if the variable contains a web URL (ie. HTTP/HTTPS protocol) and prevents the writing of links that may pose a security risk.
If the link uses a different scheme, such as javascript:
or data:
, and you are sure of its content,
you can disable the check using |nocheck
.
{var $link = 'javascript:window.close()'}
<a href={$link}>checked</a>
<a href={$link|nocheck}>unchecked</a>
Outputs:
<a href="">checked</a>
<a href="javascript:window.close()">unchecked</a>
See also checkUrl.
noescape
Disables automatic escaping.
{var $trustedHtmlString = '<b>hello</b>'}
Escaped: {$trustedHtmlString}
Unescaped: {$trustedHtmlString|noescape}
Outputs:
Escaped: <b>hello</b>
Unescaped: <b>hello</b>
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.
number (int $decimals=0, string
$decPoint='.'
, string $thousandsSep=','
)
Formats a number to a specified number of decimal places. If the locale is set, the corresponding decimal and thousand separators are used.
{1234.20|number} {* 1,234 *}
{1234.20|number:1} {* 1,234.2 *}
{1234.20|number:2} {* 1,234.20 *}
{1234.20|number:2, ',', ' '} {* 1 234,20 *}
number (string $format)
The format
parameter allows you to define the appearance of numbers exactly according to your needs. This requires
the locale to be set. The format consists of several special
characters, a complete description of which can be found in the DecimalFormat documentation:
0
mandatory digit, always displayed even if it's zero#
optional digit, displayed only if the number actually has a digit in this place@
significant digit, helps display the number with a certain number of significant digits.
indicates where the decimal separator should be (dot or comma, depending on the country),
serves to separate groups of digits, most often thousands%
multiplies the number by 100 and adds the percent sign
Let's look at some examples. In the first example, two decimal places are mandatory; in the second, they are optional. The third example shows padding with zeros from the left and right, the fourth displays only existing digits:
{1234.5|number: '#,##0.00'} {* 1,234.50 *}
{1234.5|number: '#,##0.##'} {* 1,234.5 *}
{1.23 |number: '000.000'} {* 001.230 *}
{1.2 |number: '##.##'} {* 1.2 *}
Significant digits determine how many digits, regardless of the decimal point, should be displayed, rounding if necessary:
{1234|number: '@@'} {* 1200 *}
{1234|number: '@@@'} {* 1230 *}
{1234|number: '@@@#'} {* 1234 *}
{1.2345|number: '@@@'} {* 1.23 *}
{0.00123|number: '@@'} {* 0.0012 *}
An easy way to display a number as a percentage. The number is multiplied by 100, and the %
sign is added:
{0.1234|number: '#.##%'} {* 12.34% *}
We can define a different format for positive and negative numbers, separated by a ;
character. This way, for
example, positive numbers can be displayed with a +
sign:
{42|number: '#.##;(#.##)'} {* 42 *}
{-42|number: '#.##;(#.##)'} {* (42) *}
{42|number: '+#.##;-#.##'} {* +42 *}
{-42|number: '+#.##;-#.##'} {* -42 *}
Remember that the actual appearance of numbers may vary depending on the country settings. For example, in some countries, a comma is used instead of a dot as the decimal separator. This filter automatically takes this into account, so you don't need to worry about it.
padLeft (int $length, string
$pad=' '
)
Pads a string to a certain length with another string from the left.
{='hello'|padLeft: 10, '123'} {* outputs '12312hello' *}
padRight (int $length, string
$pad=' '
)
Pads a string to a certain length with another string from the right.
{='hello'|padRight: 10, '123'} {* outputs 'hello12312' *}
query
Dynamically generates a query string in a URL:
<a href="http://example.com/?{[name: 'John Doe', age: 43]|query}">click</a>
<a href="http://example.com/?search={$search|query}">search</a>
Outputs:
<a href="http://example.com/?name=John+Doe&age=43">click</a>
<a href="http://example.com/?search=Foo+Bar">search</a>
Keys with a null
value are omitted.
See also escapeUrl.
random
Returns a random element of an array or a random character of a string:
{=[1, 2, 3, 4]|random} {* outputs e.g.: 3 *}
{='abcd'|random} {* outputs e.g.: 'b' *}
repeat (int $count)
Repeats the string x-times.
{='hello'|repeat: 3} {* outputs 'hellohellohello' *}
replace (string|array $search, string
$replace=''
)
Replaces all occurrences of the search string with the replacement string.
{='hello world'|replace: 'world', 'friend'} {* outputs 'hello friend' *}
Multiple replacements can be made at once:
{='hello world'|replace: [h => l, l => h]} {* outputs 'lehho worhd' *}
replaceRE (string $pattern, string
$replace=''
)
Performs a regular expression search and replace.
{='hello world'|replaceRE: '/l.*/', 'l'} {* outputs 'hel' *}
reverse
Reverses the given string or array.
{var $s = 'Nette'}
{$s|reverse} {* outputs 'etteN' *}
{var $a = ['N', 'e', 't', 't', 'e']}
{$a|reverse} {* returns ['e', 't', 't', 'e', 'N'] *}
round (int $precision=0)
Rounds a number to the given precision.
{=3.4|round} {* outputs 3 *}
{=3.5|round} {* outputs 4 *}
{=135.79|round:1} {* outputs 135.8 *}
{=135.79|round:3} {* outputs 135.79 *}
slice (int $start, ?int $length=null, bool $preserveKeys=false)
Extracts a slice of an array or a string.
{='hello'|slice: 1, 2} {* outputs 'el' *}
{=['a', 'b', 'c']|slice: 1, 2} {* outputs ['b', 'c'] *}
The filter works like the PHP function array_slice
for arrays or mb_substr
for strings, with a
fallback to the iconv_substr
function in UTF‑8 mode.
If start
is non-negative, the sequence will start at that offset from the beginning of the array/string. If
start
is negative, the sequence will start that far from the end.
If length
is given and is positive, then the sequence will have up to that many elements. If the input is shorter
than the length
, then only the available elements will be present. If length
is given and is negative,
the sequence will stop that many elements from the end of the input. If it is omitted, the sequence will have everything from
start
up until the end of the input.
By default, the filter reorders and resets the integer array keys. This behavior can be changed by setting
preserveKeys
to true. String keys are always preserved, regardless of this parameter.
sort (?Closure $comparison, string|int|\Closure|null $by=null, string|int|\Closure|bool $byKey=false)
The filter sorts elements of an array or iterator and preserves their associative keys. When a locale is set, the sorting follows its rules unless a custom comparison function is specified.
{foreach ($names|sort) as $name}
...
{/foreach}
Sorted array in reverse order:
{foreach ($names|sort|reverse) as $name}
...
{/foreach}
You can specify a custom comparison function for sorting (the example shows how to reverse the sort from largest to smallest):
{var $reverted = ($names|sort: fn($a, $b) => $b <=> $a)}
The |sort
filter also allows sorting elements by keys:
{foreach ($names|sort: byKey: true) as $name}
...
{/foreach}
If you need to sort a table by a specific column, you can use the by
parameter. The value 'name'
in
the example specifies that sorting will be done by $item->name
or $item['name']
, depending on whether
$item
is an array or an object:
{foreach ($items|sort: by: 'name') as $item}
{$item->name}
{/foreach}
You can also define a callback function that determines the value to sort by:
{foreach ($items|sort: by: fn($item) => $item->category->name) as $item}
{$item->name}
{/foreach}
The byKey
parameter can be used in the same way.
spaceless
Removes unnecessary whitespace from the output. You can also use the alias strip
.
{block |spaceless}
<ul>
<li>Hello</li>
</ul>
{/block}
Outputs:
<ul> <li>Hello</li> </ul>
stripHtml
Converts HTML to plain text. That is, it removes HTML tags and converts HTML entities to text characters.
{='<p>one < two</p>'|stripHtml} {* outputs 'one < two' *}
The resulting plain text can naturally contain characters that represent HTML tags, for example
'<p>'|stripHtml
is converted to <p>
. Never output the resulting text with
|noescape
, as this can lead to a security vulnerability.
substr (int $offset, ?int $length=null)
Extracts a portion of a string. This filter has been replaced by the slice filter.
{$string|substr: 1, 2}
translate (…$args)
Translates expressions into other languages. To make the filter available, you need to set up the translator. You can also use the tags for translation.
<a href="basket">{='Basket'|translate}</a>
<span>{$item|translate}</span>
trim (string
$charlist=" \t\n\r\0\x0B\u{A0}"
)
Strips whitespace (or other characters) from the beginning and end of a string.
{=' I like Latte. '|trim} {* outputs 'I like Latte.' *}
{=' I like Latte.'|trim: '.'} {* outputs ' I like Latte' *}
truncate (int $length, string
$append='…'
)
Truncates a string to the specified maximum length, while trying to preserve whole words. If the string is shortened, it adds an ellipsis at the end (can be changed with the second parameter).
{var $title = 'Hello, how are you?'}
{$title|truncate:5} {* Hell… *}
{$title|truncate:17} {* Hello, how are… *}
{$title|truncate:30} {* Hello, how are you? *}
upper
Converts a string to uppercase. Requires the mbstring
PHP extension.
{='latte'|upper} {* outputs 'LATTE' *}
See also capitalize, firstUpper, lower.
webalize
Adjusts a UTF‑8 string to the format used in URLs.
Converts to ASCII. Converts spaces to hyphens. Removes characters that are not alphanumeric, underscores, or hyphens. Converts to lowercase. Also strips leading and trailing whitespace.
{var $s = 'Our 10th product'}
{$s|webalize} {* outputs 'our-10th-product' *}
Requires the nette/utils library.