Nette Documentation Preview

syntax
Синтаксис
*********

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

Нижче наведено мінімальний шаблон, що ілюструє кілька базових елементів: теги, n:attributes, коментарі та фільтри.

```latte
{* це коментар *}
<ul n:if="$items">               {* n:if is n:atribut *}
{foreach $items as $item}        {* тег, що представляє цикл foreach *}
	<li>{$item|capitalize}</li>  {* тег, що виводить змінну з фільтром *}
{/foreach}                       {* кінець циклу *}
</ul>
```

Давайте докладніше розглянемо ці важливі елементи і те, як вони можуть допомогти вам створити неймовірний шаблон.


Теги .[#toc-tags]
=================

Шаблон містить теги, які керують логікою шаблону (наприклад, цикли *foreach*) або вихідними виразами. Для обох випадків використовується один роздільник `{ ... }`, тому вам не потрібно думати про те, який роздільник використовувати в тій чи іншій ситуації, як в інших системах.
Якщо за символом `{` слідує лапка або пробіл, Latte не вважає його початком тега, тому ви можете без проблем використовувати у своїх шаблонах конструкції JavaScript, JSON або правила CSS.

Дивіться [огляд усіх тегів |tags]. Крім того, ви можете створювати [власні теги |extending-latte#Tags].


Latte розуміє PHP .[#toc-latte-understands-php]
===============================================

Усередині тегів можна використовувати вирази PHP, які ви добре знаєте:

- змінні
- рядки (включно з HEREDOC і NOWDOC), масиви, числа тощо.
- [оператори |https://www.php.net/manual/en/language.operators.php]
- виклики функцій і методів (які можуть бути обмежені [пісочницею |sandbox])
- [відповідність |https://www.php.net/manual/en/control-structures.match.php]
- [анонімні функції |https://www.php.net/manual/en/functions.arrow.php]
- [зворотні виклики |https://www.php.net/manual/en/functions.first_class_callable_syntax.php]
- багаторядкові коментарі `/* ... */`
- і т.д.

Крім того, Latte додає кілька [приємних розширень |#Syntactic-Sugar] до синтаксису PHP.


n:attributes .[#toc-n-attributes]
=================================

Кожен парний тег, наприклад `{if} … {/if}`, що працює з одним елементом HTML, може бути записаний у нотації [n:attribute |#n:attribute]. Наприклад, `{foreach}` у наведеному вище прикладі можна записати і так:

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

Функціональність тоді відповідає елементу HTML, у якому вона записана:

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

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

Prints:

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

Використовуючи префікс `inner-`, ми можемо змінити поведінку так, щоб функціональність застосовувалася тільки до тіла елемента:

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

Відбитки:

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

Або за допомогою префікса `tag-` функціональність застосовується тільки до HTML-тегів:

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

Залежно від значення змінної `$url` буде виведено таке:

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

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

Однак n:attributes - це не тільки скорочення для парних тегів, є й деякі чисті n:attributes, наприклад, найкращий друг кодера [n:class |tags#n-class].


Фільтри .[#toc-filters]
=======================

Див. короткий опис [стандартних фільтрів |filters].

Latte дозволяє викликати фільтри за допомогою знака труби (пробіл перед фільтром допускається):

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

Фільтри можуть бути з'єднані в ланцюжок, у цьому разі вони застосовуються в порядку зліва направо:

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

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

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

Фільтри можуть бути застосовані до виразу:

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

На блоці:

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

Або безпосередньо на значенні (у поєднанні з [`{=expr}` | https://latte.nette.org/uk/tags#printing] тег):
```latte
<h1>{='  Hello world  '|trim}<h1>
```


Динамічні теги HTML .[#toc-dynamic-html-tags]
=============================================

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

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

Наприклад, код вище може згенерувати `<h1>Heading</h1>` або `<h2>Heading</h2>` в залежності від значення змінної `$level`. Динамічні HTML-теги в Latte завжди повинні бути парними. Їх альтернативою є [n:tag |tags#n:tag].

Оскільки Latte є безпечною системою шаблонів, вона перевіряє, що результуюче ім'я тегу є дійсним і не містить небажаних або шкідливих значень. Вона також гарантує, що ім'я кінцевого тегу завжди збігається з ім'ям початкового тегу.


Коментарі .[#toc-comments]
==========================

Коментарі пишуться таким чином і не потрапляють у виведення:

```latte
{* це коментар у Latte *}
```

Коментарі PHP працюють усередині тегів:

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


Синтаксичний цукор .[#toc-syntactic-sugar]
==========================================


Рядки без лапок .[#toc-strings-without-quotation-marks]
-------------------------------------------------------

Для простих рядків лапки можна не ставити:

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

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

Прості рядки - це рядки, які складаються виключно з літер, цифр, підкреслень, дефісів і крапок. Вони не повинні починатися з цифри і не повинні починатися або закінчуватися дефісом.
Він не повинен складатися тільки із великих літер і знаків підкреслення, тому що тоді він вважається константою (наприклад, `PHP_VERSION`).
І він не повинен перетинатися з ключовими словами `and`, `array`, `clone`, `default`, `false`, `in`, `instanceof`, `new`, `null`, `or`, `return`, `true`, `xor`.


Короткий тернарний оператор .[#toc-short-ternary-operator]
----------------------------------------------------------

Якщо третє значення тернарного оператора порожнє, його можна опустити:

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

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


Сучасна ключова нотація в масиві .[#toc-modern-key-notation-in-the-array]
-------------------------------------------------------------------------

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

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

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


Фільтри .[#toc-filters]
-----------------------

Фільтри можна використовувати для будь-якого виразу, просто помістіть все в дужки:

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


Оператор `in` .[#toc-operator-in]
---------------------------------

Оператор `in` може бути використаний для заміни функції `in_array()`. Порівняння завжди суворе:

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


Вікно в історію .[#toc-a-window-into-history]
---------------------------------------------

За свою історію 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 .[#toc-php-limitations-in-latte]
======================================================

У Latte можна писати лише PHP-вирази. Тобто не можна використовувати вирази, що закінчуються крапкою з комою. Не можна оголошувати класи або використовувати [керуючі структури |https://www.php.net/manual/en/language.control-structures.php], такі як `if`, `foreach`, `switch`, `return`, `try`, `throw` та інші, замість яких Latte пропонує свої [теги |tags].
Ви також не можете використовувати [атрибути |https://www.php.net/manual/en/language.attributes.php], [бектики |https://www.php.net/manual/en/language.operators.execution.php] або будь-які [магічні константи |https://www.php.net/manual/en/language.constants.magic.php].
Ви навіть не можете використовувати `unset`, `echo`, `include`, `require`, `exit`, `eval`, тому що це не функції, а спеціальні конструкції мови PHP, а отже, не вирази. Підтримуються тільки багаторядкові коментарі `/* ... */`.

Однак ви можете обійти ці обмеження, активувавши розширення [RawPhpExtension |develop#RawPhpExtension], яке дає змогу використовувати будь-який PHP-код у тезі `{php ...}` під відповідальність автора шаблону.

Синтаксис

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

Нижче наведено мінімальний шаблон, що ілюструє кілька базових елементів: теги, n:attributes, коментарі та фільтри.

{* це коментар *}
<ul n:if="$items">               {* n:if is n:atribut *}
{foreach $items as $item}        {* тег, що представляє цикл foreach *}
	<li>{$item|capitalize}</li>  {* тег, що виводить змінну з фільтром *}
{/foreach}                       {* кінець циклу *}
</ul>

Давайте докладніше розглянемо ці важливі елементи і те, як вони можуть допомогти вам створити неймовірний шаблон.

Теги

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

Дивіться огляд усіх тегів. Крім того, ви можете створювати власні теги.

Latte розуміє PHP

Усередині тегів можна використовувати вирази PHP, які ви добре знаєте:

Крім того, Latte додає кілька приємних розширень до синтаксису PHP.

n:attributes

Кожен парний тег, наприклад {if} … {/if}, що працює з одним елементом HTML, може бути записаний у нотації n:attribute. Наприклад, {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>

Prints:

<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 буде виведено таке:

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

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

Однак n:attributes – це не тільки скорочення для парних тегів, є й деякі чисті n:attributes, наприклад, найкращий друг кодера n:class.

Фільтри

Див. короткий опис стандартних фільтрів.

Latte дозволяє викликати фільтри за допомогою знака труби (пробіл перед фільтром допускається):

<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 */}

Синтаксичний цукор

Рядки без лапок

Для простих рядків лапки можна не ставити:

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

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

Прості рядки – це рядки, які складаються виключно з літер, цифр, підкреслень, дефісів і крапок. Вони не повинні починатися з цифри і не повинні починатися або закінчуватися дефісом. Він не повинен складатися тільки із великих літер і знаків підкреслення, тому що тоді він вважається константою (наприклад, PHP_VERSION). І він не повинен перетинатися з ключовими словами and, array, clone, default, false, in, instanceof, new, null, or, return, true, xor.

Короткий тернарний оператор

Якщо третє значення тернарного оператора порожнє, його можна опустити:

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

abbreviated: {$stock ? 'In stock'}

Сучасна ключова нотація в масиві

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

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

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

Фільтри

Фільтри можна використовувати для будь-якого виразу, просто помістіть все в дужки:

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

Оператор in

Оператор in може бути використаний для заміни функції in_array(). Порівняння завжди суворе:

{* like 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 ...} під відповідальність автора шаблону.