Синтаксис

Синтаксис Latte возник из практических требований веб-дизайнеров. Мы искали самый удобный синтаксис, с помощью которого можно элегантно записывать даже конструкции, которые в противном случае представляют собой настоящую головоломку. В то же время все выражения пишутся точно так же, как в PHP, так что вам не придется учить новый язык. Вы просто используете то, что уже давно умеете.

Ниже приведен минимальный шаблон, иллюстрирующий несколько основных элементов: теги, n:атрибуты, комментарии и фильтры.

{* это комментарий *}
<ul n:if=$items>                  {* n:if - это n:атрибут *}
{foreach $items as $item}         {* тег, представляющий цикл foreach *}
	<li>{$item|capitalize}</li>   {* тег, выводящий переменную с фильтром *}
{/foreach}                        {* конец цикла *}
</ul>

Давайте подробнее рассмотрим эти важные элементы и то, как они могут помочь вам создать потрясающий шаблон.

Теги

Шаблон содержит теги, которые управляют логикой шаблона (например, циклы foreach) или выводят выражения. Для обоих используется единый разделитель { ... }, так что вам не нужно думать, какой разделитель использовать в какой ситуации, как это бывает в других системах. Если за символом { следует кавычка или пробел, Latte не считает его началом тега, благодаря чему вы можете без проблем использовать в шаблонах и JavaScript-конструкции, JSON или правила в CSS.

Посмотрите обзор всех тегов. Кроме того, вы можете создавать и пользовательские теги.

Latte понимает PHP

Внутри тегов вы можете использовать PHP-выражения, которые вам хорошо знакомы:

Кроме того, Latte дополняет синтаксис PHP несколькими приятными расширениями.

n:атрибуты

Все парные теги, например {if} … {/if}, оперирующие над одним HTML-элементом, можно переписать в виде n:атрибутов. Так можно было бы записать, например, и {foreach} во вводном примере:

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

Функциональность тогда относится к HTML-элементу, в который она помещена:

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

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

выводит:

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

С помощью префикса inner- мы можем изменить поведение так, чтобы оно относилось только к внутренней части элемента:

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

Выведется:

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

Или с помощью префикса tag- применим функциональность только к самим HTML-тегам:

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

Что выведет в зависимости от переменной $url:

{* когда $url пуст *}
<p>Title</p>

{* когда $url содержит 'https://nette.org' *}
<p><a href="https://nette.org">Title</a></p>

Однако n:атрибуты — это не просто сокращение для парных тегов. Существуют и чистые n:атрибуты, такие как n:href или очень удобный помощник кодера n:class.

Фильтры

Посмотрите обзор стандартных фильтров.

Фильтры записываются после вертикальной черты (перед ней может быть пробел):

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

Фильтры можно объединять в цепочку, и они применяются в порядке слева направо:

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

Параметры указываются после имени фильтра, разделенные двоеточиями или запятыми:

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

Фильтры можно применять и к выражению:

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

К блоку:

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

Или непосредственно к значению (в сочетании с тегом {=expr}):

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

Динамические HTML-теги

Latte поддерживает динамические HTML-теги, которые полезны, когда вам нужна гибкость в именах тегов:

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

Приведенный выше код может, например, генерировать <h1>Heading</h1> или <h2>Heading</h2> в зависимости от значения переменной $level. Динамические HTML-теги в Latte всегда должны быть парными. Их альтернативой является n:tag.

Поскольку Latte является безопасной системой шаблонов, он проверяет, является ли результирующее имя тега допустимым и не содержит ли оно нежелательных или вредоносных значений. Кроме того, он гарантирует, что имя закрывающего тега всегда будет таким же, как имя открывающего тега.

Комментарии

Комментарии записываются таким образом и в вывод не попадают:

{* это комментарий в Latte *}

Внутри тегов работают PHP-комментарии:

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

Синтаксический сахар

Строки без кавычек

Для простых строк можно опускать кавычки:

как в PHP:  {var $arr = ['hello', 'btn--default', '€']}

сокращенно:    {var $arr = [hello, btn--default, €]}

Простые строки — это те, которые состоят исключительно из букв, цифр, подчеркиваний, дефисов и точек. Они не должны начинаться с цифры и не должны начинаться или заканчиваться дефисом. Они не должны состоять только из заглавных букв и подчеркиваний, потому что тогда они считаются константами (например, PHP_VERSION). И они не должны конфликтовать с ключевыми словами: and, array, clone, default, false, in, instanceof, new, null, or, return, true, xor.

Константы

Поскольку для простых строк можно опускать кавычки, рекомендуется для отличия записывать глобальные константы с косой чертой в начале:

{if \PROJECT_ID === 1} ... {/if}

Эта запись полностью валидна в самом PHP, косая черта говорит о том, что константа находится в глобальном пространстве имен.

Сокращенный тернарный оператор

Если третье значение тернарного оператора пустое, его можно опустить:

как в PHP:  {$stock ? 'В наличии' : ''}

сокращенно:    {$stock ? 'В наличии'}

Современная запись ключей в массиве

Ключи в массиве можно записывать подобно именованным параметрам при вызове функций:

как в PHP:  {var $arr = ['one' => 'item 1', 'two' => 'item 2']}

современно:     {var $arr = [one: 'item 1', two: 'item 2']}

Фильтры

Фильтры можно применять к любым выражениям, достаточно заключить целое в скобки:

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

Оператор in

Оператором in можно заменить функцию in_array(). Сравнение всегда строгое:

{* аналог in_array($item, $items, true) *}
{if $item in $items}
	...
{/if}

Исторический экскурс

Latte в ходе своей истории представило целый ряд синтаксических улучшений, которые через несколько лет появились в самом PHP. Например, в Latte можно было писать массивы как [1, 2, 3] вместо array(1, 2, 3) или использовать nullsafe оператор $obj?->foo задолго до того, как это стало возможным в самом PHP. Latte также ввело оператор распаковки массива (expand) $arr, который является эквивалентом сегодняшнего оператора ...$arr из PHP.

Undefined-safe оператор ??->, который является аналогом nullsafe оператора ?->, но не вызывает ошибку, если переменная не существует, возник по историческим причинам, и сегодня мы рекомендуем использовать стандартный PHP-оператор ?->.

Ограничения PHP в Latte

В Latte можно записывать только PHP-выражения. То есть нельзя использовать инструкции, заканчивающиеся точкой с запятой. Нельзя объявлять классы или использовать управляющие структуры, например if, foreach, switch, return, try, throw и другие, вместо которых Latte предлагает свои теги. Также нельзя использовать атрибуты, обратные кавычки или некоторые магические константы. Нельзя использовать и unset, echo, include, require, exit, eval, потому что это не функции, а специальные языковые конструкции PHP, и они не являются выражениями. Комментарии поддерживаются только многострочные /* ... */.

Однако эти ограничения можно обойти, активировав расширение RawPhpExtension, благодаря которому можно затем использовать в теге {php ...} любой PHP-код под ответственность автора шаблона.

версия: 3.0