Синтаксис
Синтаксис 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-выражения, которые вам хорошо знакомы:
- переменные
- строки (включая HEREDOC и NOWDOC), массивы, числа и т.д.
- операторы
- вызовы функций и методов (которые можно ограничить песочницей)
- match
- анонимные функции
- коллбэки
- многострочные комментарии
/* ... */
- и т.д…
Кроме того, 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-код под ответственность
автора шаблона.