Синтаксис
Синтаксис 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), масиви, числа тощо.
- оператори
- виклики функцій та методів (які можна обмежити sandbox)
- match
- анонімні функції
- callback-функції
- багаторядкові коментарі
/* ... */
- тощо…
Крім того, 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-код на
відповідальність автора шаблону.