Nette Documentation Preview

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

.[perex]
Синтаксисът на Latte произлиза от практическите изисквания на уеб дизайнерите. Търсихме най-удобния синтаксис, с който елегантно да запишете дори конструкции, които иначе представляват истинско предизвикателство. Същевременно всички изрази се пишат по абсолютно същия начин като в PHP, така че не е необходимо да учите нов език. Просто използвате това, което вече знаете.

По-долу е представен минимален шаблон, който илюстрира няколко основни елемента: тагове, n:атрибути, коментари и филтри.

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

Нека разгледаме по-отблизо тези важни елементи и как те могат да ви помогнат да създадете страхотен шаблон.


Тагове
======

Шаблонът съдържа тагове, които управляват логиката на шаблона (например цикли *foreach*) или извеждат изрази. И за двете се използва единствен разделител `{ ... }`, така че не е необходимо да мислите кой разделител в коя ситуация да използвате, както е при други системи. Ако след знака `{` следва кавичка или интервал, Latte не го счита за начало на таг, благодарение на което можете в шаблоните безпроблемно да използвате и JavaScript конструкции, JSON или правила в CSS.

Разгледайте [преглед на всички тагове|tags]. Освен това можете да създавате и [собствени тагове|custom tags].


Latte разбира PHP
=================

Вътре в таговете можете да използвате PHP изрази, които добре познавате:

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

Освен това Latte допълва синтаксиса на PHP с няколко [приятни разширения |#Синтактичен захар].


n:атрибути
==========

Всички двойни тагове, например `{if} … {/if}`, опериращи над един HTML елемент, могат да бъдат преписани във вид на n:атрибути. Така би могло да се запише например и `{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>
```

извежда:

```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
{* когато $url е празно *}
<p>Title</p>

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

Въпреки това, n:атрибутите не са само съкращение за двойни тагове. Съществуват и чисти n:атрибути, като например [n:href |application:creating-links#В шаблона на презентера] или изключително удобния помощник за кодера [n:class |tags#n:class].


Филтри
======

Разгледайте прегледа на [стандартни филтри |filters].

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

```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}` |tags#Извеждане]):
```latte
<h1>{='  Hello world  '|trim}<h1>
```


Динамични HTML тагове .{data-version:3.0.9}
===========================================

Latte поддържа динамични HTML тагове, които са полезни, когато се нуждаете от гъвкавост в имената на таговете:

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

Горният код може например да генерира `<h1>Heading</h1>` или `<h2>Heading</h2>` в зависимост от стойността на променливата `$level`. Динамичните HTML тагове в Latte трябва винаги да бъдат двойни. Тяхната алтернатива е [n:tag |tags#n:tag].

Тъй като Latte е сигурна система за шаблони, тя проверява дали резултатното име на тага е валидно и не съдържа никакви нежелани или вредни стойности. Освен това гарантира, че името на затварящия таг винаги ще бъде същото като името на отварящия таг.


Коментари
=========

Коментарите се записват по този начин и не попадат в изхода:

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

Вътре в таговете работят PHP коментари:

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


Синтактичен захар
=================


Низове без кавички
------------------

При прости низове могат да се пропуснат кавичките:

```latte
като в 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`.


Константи
---------

Тъй като при прости низове могат да се пропускат кавичките, препоръчваме за разграничение да се записват глобални константи с наклонена черта в началото:

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

Този запис е напълно валиден в самото PHP, наклонената черта казва, че константата е в глобалното пространство от имена.


Съкратен тернарен оператор
--------------------------

Ако третата стойност на тернарния оператор е празна, може да се пропусне:

```latte
като в PHP:  {$stock ? 'Налично' : ''}

съкратено:    {$stock ? 'Налично'}
```


Модерен запис на ключове в масив
--------------------------------

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

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

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


Филтри
------

Филтрите могат да се използват за всякакви изрази, достатъчно е цялото да се затвори в скоби:

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


Оператор `in`
-------------

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

```latte
{* аналог на 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 изрази. Тоест не могат да се използват стейтмънти, завършващи с точка и запетая. Не могат да се декларират класове или да се използват [контролни структури |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:атрибути, коментари и филтри.

{* това е коментар *}
<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 код на отговорност на автора на шаблона.