Nette Documentation Preview

syntax
Създаване на URL връзки
***********************

<div class=perex>

Създаването на връзки в Nette е толкова лесно, колкото да посочите с пръст. Просто насочете курсора и системата ще свърши цялата работа вместо вас. Ние ви показваме:

- Как да създавате връзки в шаблони и на други места
- как да маркирате връзка в текущата страница
- Какво да правим с невалидните връзки

</div>


Благодарение на [двупосочното маршрутизиране |routing] не се налага да кодирате URL адресите на приложенията в шаблони или код, който може да се промени по-късно или да бъде сложен за съставяне. Просто посочете презентатора и действието във връзката, подайте всички параметри и рамката сама ще генерира URL адреса. Всъщност това е много подобно на извикване на функция. Ще ви хареса.


В шаблона на водещия. .[#toc-in-the-presenter-template]
=======================================================

В повечето случаи създаваме връзки в шаблони, а атрибутът `n:href` е чудесен помощник:

```latte
<a n:href="Product:show">подробнее</a>
```

Обърнете внимание, че вместо HTML атрибута `href` сме използвали [n:атрибута |latte:syntax#n:attributes] `n:href`. Стойността му не е URL адресът, както сте свикнали да виждате в атрибута `href`, а името на водещия и действието.

Щракването върху връзката, казано по-просто, е нещо като извикване на метода `ProductPresenter::renderShow()`. И ако в сигнатурата му има параметри, можем да го извикаме с аргументи:

```latte
<a n:href="Product:show $product->id, $product->slug">подробнее</a>
```

Можем също така да предаваме именувани параметри. Следната връзка предава параметъра `lang` със стойност `en`:

```latte
<a n:href="Product:show $product->id, lang: en">подробнее</a>
```

Ако методът `ProductPresenter::renderShow()` няма `$lang` в сигнатурата си, той може да извлече стойността на параметъра, като използва `$lang = $this->getParameter('lang')` или от [свойството |presenters#Request Parameters].

Ако параметрите се съхраняват в масив, те могат да бъдат разширени с помощта на оператора `(expand)` (нещо като `...` в PHP, но работи с асоциативни масиви):

```latte
{var $args = [$product->id, lang => en]}
<a n:href="Product:show (expand) $args">подробнее</a>
```

Така наречените [постоянни параметри |presenters#Persistent-Parameters] също се предават автоматично в референции.

Атрибутът `n:href` е много полезен за HTML тагове. `<a>`. Ако искаме да покажем връзката на друго място, например в текста, използваме `{link}`:

```latte
URL: {link Home:default}
```


В кода .[#toc-in-the-code]
==========================

Методът `link()` се използва за създаване на връзка в презентатора:

```php
$url = $this->link('Product:show', $product->id);
```

Параметрите могат да се предават и като масив, който може да съдържа именувани параметри:

```php
$url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
```

Връзки могат да се създават и без презентатор, като се използва [LinkGenerator |#LinkGenerator] и неговият метод `link()`.


Препратки към водещия .[#toc-links-to-presenter]
================================================

Ако целта на връзката е да се свърже с представящия и действието, тя има следния синтаксис:

```
[//] [[[[:]module:]presenter:]action | this] [#fragment]
```

Форматът се поддържа от всички тагове на Latte и всички методи на презентатора, които работят с връзки, т.е. `n:href`, `{link}`, `{plink}`, `link()`, `lazyLink()`, `isLinkCurrent()`, `redirect()`, `redirectPermanent()`, `forward()`, `canonicalize()`, както и [LinkGenerator |#LinkGenerator]. Следователно, дори ако в примерите се използва `n:href`, тук може да се използва всяка от функциите.

Следователно основната форма е `Presenter:action`:

```latte
<a n:href="Home:default">главная страница</a>
```

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

```latte
<a n:href="default">главная страница</a>
```

Ако действието е `default`, можем да го пропуснем, но двоеточието трябва да остане:

```latte
<a n:href="Home:">главная страница</a>
```

Връзките могат да сочат и към други [модули |modules]. Тук връзките се разграничават на относителни към подмодули или абсолютни. Принципът е подобен на дисковите пътища, само че с двоеточия вместо с наклонени черти. Да предположим, че водещият е част от модул `Front`, тогава записваме:

```latte
<a n:href="Shop:Product:show">ссылка на Front:Shop:Product:show</a>
<a n:href=":Admin:Product:show">ссылка на Admin:Product:show</a>
```

Специален случай е [самореференцията |#Link-to-Current-Page]. Тук ще напишем `this` като цел.

```latte
<a n:href="this">refresh</a>
```

Можем да направим връзка към определена част от HTML страницата чрез така наречения фрагмент след символа хеш `#`:

```latte
<a n:href="Home:#main">ссылка на Home:default и фрагмент #main</a>
```


Абсолютни пътища .[#toc-absolute-paths]
=======================================

Връзките, генерирани от `link()` или `n:href`, винаги са абсолютни пътища (т.е. започват с `/`), но не и абсолютни URL адреси с протокол и домейн, като `https://domain`.

За да създадете абсолютен URL адрес, добавете две наклонени черти в началото (например `n:href="//Home:"`). Или можете да превключите презентатора да генерира само абсолютни връзки, като зададете `$this->absoluteUrls = true`.


Връзка към текущата страница .[#toc-link-to-current-page]
=========================================================

Целта `this` ще създаде връзка към текущата страница:

```latte
<a n:href="this">обновить</a>
```

В същото време всички параметри, посочени в сигнатурата на `action<Action>()` или `render<View>()` ако методът `action<Action>()` не са дефинирани, се прехвърлят. Така че, ако се намираме на страниците `Product:show` и `id:123`, връзката към `this` също ще предаде този параметър.

Разбира се, можете да зададете параметрите и директно:

```latte
<a n:href="this refresh: 1">обновить</a>
```

Методът на водещия `isLinkCurrent()` определя дали целта на връзката съвпада с текущата страница. Това може да се използва например в шаблон за разграничаване на връзки и т.н.

Параметрите са същите като при метода `link()`, но можете да използвате и символа `*` вместо конкретно действие, което означава всяко действие на водещия.

```latte
{if !$presenter->isLinkCurrent('Admin:login')}
	<a n:href="Admin:login">Войти</a>
{/if}

<li n:class="$presenter->isLinkCurrent('Product:*') ? active">
	<a n:href="Product:">...</a>
</li>
```

Съкратената форма може да се използва в комбинация с `n:href` в един и същ елемент:

```latte
<a n:class="$presenter->isLinkCurrent() ? active" n:href="Product:detail">...</a>
```

Заместващият символ `*` замества само действието на презентатора, а не самия презентатор.

За да разберем дали се намираме в определен модул или негов подмодул, можем да използваме метода `$presenter->isModuleCurrent(moduleName)`.

```latte
<li n:class="$presenter->isModuleCurrent('MyEshop:Users') ? active">
	<a n:href="Product:">...</a>
</li>
```


Връзки към сигнала .[#toc-links-to-signal]
==========================================

Целта на препратката може да бъде не само водещ и действие, но и [сигнал |components#Signal] (те извикват метод `handle<Signal>()`). Синтаксисът е следният:

```
[//] [sub-component:]signal! [#fragment]
```

Поради това сигналът е подчертан с възклицателен знак:

```latte
<a n:href="click!">signal</a>
```

Можете също така да създадете препратка към сигнал на подкомпонент (или подкомпонент):

```latte
<a n:href="componentName:click!">signal</a>
```


Връзки към компонентите .[#toc-links-in-component]
==================================================

Тъй като [компонентите |components] са отделни единици за многократна употреба, които не трябва да имат никаква връзка с околните презентатори, препратките работят по малко по-различен начин. Атрибутът Latte `n:href` и тагът `{link}`, както и методите на компонентите, като например `link()` и други, винаги третират целта **като име на сигнал**. Затова не е необходимо да използвате възклицателен знак:

```latte
<a n:href="click">сигнал, не действие</a>
```

Ако искаме да направим препратка към презентаторите в шаблона на компонента, използваме тага `{plink}`:

```latte
<a href={plink Home:default}>главная страница</a>
```

или в кода

```php
$this->getPresenter()->link('Home:default')
```


Псевдоними .[#toc-aliases]{data-version:v3.2.2}
===============================================

Понякога е полезно да зададете лесно запомнящ се псевдоним на двойка презентатор:действие. Например, можете да наречете началната страница `Front:Home:default` просто `home` или `Admin:Dashboard:default` - `admin`.

Псевдонимите се дефинират в [конфигурацията |configuration] под ключа `application › aliases`:

```neon
application:
    aliases:
        home: Front:Home:default
        admin: Admin:Dashboard:default
        sign: Front:Sign:in
```

Във връзките те се записват с помощта на символа at, например:

```latte
<a n:href="@admin">administration</a>
```

Те се поддържат във всички методи, които работят с връзки, като например `redirect()` и други подобни.


Невалидни връзки .[#toc-invalid-links]
======================================

Може да се случи да създадем невалидна препратка - или защото препраща към несъществуващ презентатор, или защото предава повече параметри, отколкото целевият метод получава в сигнатурата си, или когато не може да бъде генериран URL адрес за целевото действие. Какво да се прави с невалидните препратки се определя от статичната променлива `Presenter::$invalidLinkMode`. Тя може да има една от тези стойности (константи):

- `Presenter::InvalidLinkSilent` - безшумен режим, връща символа `#` като URL
- `Presenter::InvalidLinkWarning` - връща се съобщение E_USER_WARNING
- `Presenter::InvalidLinkTextual` - визуално предупреждение, текстът на грешката се показва в линка
- `Presenter::InvalidLinkException` - Хвърлено е изключение InvalidLinkException

Настройката по подразбиране е `InvalidLinkWarning` в производствен режим и `InvalidLinkWarning | InvalidLinkTextual` в режим на разработка. `InvalidLinkWarning` няма да убие скрипта в производствена среда, но ще се регистрира предупреждение. В средата за разработка [Tracy |tracy:] ще улови предупреждението и ще покаже синя страница за грешка. Ако е зададен `InvalidLinkTextual`, водещият и компонентите ще върнат съобщение за грешка под формата на URL адрес, който е маркиран като `#error:`. За да направим такива връзки видими, можем да добавим CSS правило към нашия набор от стилове:

```css
a[href^="#error:"] {
	background: red;
	color: white;
}
```

Ако не искаме да се генерират предупреждения в средата за разработка, можем да активираме автоматичния режим на невалидна връзка в [конфигурацията |configuration].

```neon
application:
	silentLinks: true
```


LinkGenerator .[#toc-linkgenerator]
===================================

Как да създавате връзки така удобно, както с метода `link()`, но без презентатора? За тази цел разполагаме с [api:Nette\Application\LinkGenerator].

LinkGenerator е услуга, която може да се подаде през конструктора и след това да се създадат връзки чрез метода 'link()'.

Има разлика в сравнение с водещите. LinkGenerator създава всички връзки като абсолютни URL адреси. Освен това няма "текущ презентатор", така че не можете да зададете само името на действието "link('default')" или относителни пътища към модули.

Невалидните връзки винаги хвърлят изключение `Nette\Application\UI\InvalidLinkException`.

Създаване на URL връзки

Създаването на връзки в Nette е толкова лесно, колкото да посочите с пръст. Просто насочете курсора и системата ще свърши цялата работа вместо вас. Ние ви показваме:

  • Как да създавате връзки в шаблони и на други места
  • как да маркирате връзка в текущата страница
  • Какво да правим с невалидните връзки

Благодарение на двупосочното маршрутизиране не се налага да кодирате URL адресите на приложенията в шаблони или код, който може да се промени по-късно или да бъде сложен за съставяне. Просто посочете презентатора и действието във връзката, подайте всички параметри и рамката сама ще генерира URL адреса. Всъщност това е много подобно на извикване на функция. Ще ви хареса.

В шаблона на водещия.

В повечето случаи създаваме връзки в шаблони, а атрибутът n:href е чудесен помощник:

<a n:href="Product:show">подробнее</a>

Обърнете внимание, че вместо HTML атрибута href сме използвали n:атрибута n:href. Стойността му не е URL адресът, както сте свикнали да виждате в атрибута href, а името на водещия и действието.

Щракването върху връзката, казано по-просто, е нещо като извикване на метода ProductPresenter::renderShow(). И ако в сигнатурата му има параметри, можем да го извикаме с аргументи:

<a n:href="Product:show $product->id, $product->slug">подробнее</a>

Можем също така да предаваме именувани параметри. Следната връзка предава параметъра lang със стойност en:

<a n:href="Product:show $product->id, lang: en">подробнее</a>

Ако методът ProductPresenter::renderShow() няма $lang в сигнатурата си, той може да извлече стойността на параметъра, като използва $lang = $this->getParameter('lang') или от свойството.

Ако параметрите се съхраняват в масив, те могат да бъдат разширени с помощта на оператора (expand) (нещо като ... в PHP, но работи с асоциативни масиви):

{var $args = [$product->id, lang => en]}
<a n:href="Product:show (expand) $args">подробнее</a>

Така наречените постоянни параметри също се предават автоматично в референции.

Атрибутът n:href е много полезен за HTML тагове. <a>. Ако искаме да покажем връзката на друго място, например в текста, използваме {link}:

URL: {link Home:default}

В кода

Методът link() се използва за създаване на връзка в презентатора:

$url = $this->link('Product:show', $product->id);

Параметрите могат да се предават и като масив, който може да съдържа именувани параметри:

$url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);

Връзки могат да се създават и без презентатор, като се използва LinkGenerator и неговият метод link().

Ако целта на връзката е да се свърже с представящия и действието, тя има следния синтаксис:

[//] [[[[:]module:]presenter:]action | this] [#fragment]

Форматът се поддържа от всички тагове на Latte и всички методи на презентатора, които работят с връзки, т.е. n:href, {link}, {plink}, link(), lazyLink(), isLinkCurrent(), redirect(), redirectPermanent(), forward(), canonicalize(), както и LinkGenerator. Следователно, дори ако в примерите се използва n:href, тук може да се използва всяка от функциите.

Следователно основната форма е Presenter:action:

<a n:href="Home:default">главная страница</a>

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

<a n:href="default">главная страница</a>

Ако действието е default, можем да го пропуснем, но двоеточието трябва да остане:

<a n:href="Home:">главная страница</a>

Връзките могат да сочат и към други модули. Тук връзките се разграничават на относителни към подмодули или абсолютни. Принципът е подобен на дисковите пътища, само че с двоеточия вместо с наклонени черти. Да предположим, че водещият е част от модул Front, тогава записваме:

<a n:href="Shop:Product:show">ссылка на Front:Shop:Product:show</a>
<a n:href=":Admin:Product:show">ссылка на Admin:Product:show</a>

Специален случай е самореференцията. Тук ще напишем this като цел.

<a n:href="this">refresh</a>

Можем да направим връзка към определена част от HTML страницата чрез така наречения фрагмент след символа хеш #:

<a n:href="Home:#main">ссылка на Home:default и фрагмент #main</a>

Абсолютни пътища

Връзките, генерирани от link() или n:href, винаги са абсолютни пътища (т.е. започват с /), но не и абсолютни URL адреси с протокол и домейн, като https://domain.

За да създадете абсолютен URL адрес, добавете две наклонени черти в началото (например n:href="//Home:"). Или можете да превключите презентатора да генерира само абсолютни връзки, като зададете $this->absoluteUrls = true.

Целта this ще създаде връзка към текущата страница:

<a n:href="this">обновить</a>

В същото време всички параметри, посочени в сигнатурата на action<Action>() или render<View>() ако методът action<Action>() не са дефинирани, се прехвърлят. Така че, ако се намираме на страниците Product:show и id:123, връзката към this също ще предаде този параметър.

Разбира се, можете да зададете параметрите и директно:

<a n:href="this refresh: 1">обновить</a>

Методът на водещия isLinkCurrent() определя дали целта на връзката съвпада с текущата страница. Това може да се използва например в шаблон за разграничаване на връзки и т.н.

Параметрите са същите като при метода link(), но можете да използвате и символа * вместо конкретно действие, което означава всяко действие на водещия.

{if !$presenter->isLinkCurrent('Admin:login')}
	<a n:href="Admin:login">Войти</a>
{/if}

<li n:class="$presenter->isLinkCurrent('Product:*') ? active">
	<a n:href="Product:">...</a>
</li>

Съкратената форма може да се използва в комбинация с n:href в един и същ елемент:

<a n:class="$presenter->isLinkCurrent() ? active" n:href="Product:detail">...</a>

Заместващият символ * замества само действието на презентатора, а не самия презентатор.

За да разберем дали се намираме в определен модул или негов подмодул, можем да използваме метода $presenter->isModuleCurrent(moduleName).

<li n:class="$presenter->isModuleCurrent('MyEshop:Users') ? active">
	<a n:href="Product:">...</a>
</li>

Целта на препратката може да бъде не само водещ и действие, но и сигнал (те извикват метод handle<Signal>()). Синтаксисът е следният:

[//] [sub-component:]signal! [#fragment]

Поради това сигналът е подчертан с възклицателен знак:

<a n:href="click!">signal</a>

Можете също така да създадете препратка към сигнал на подкомпонент (или подкомпонент):

<a n:href="componentName:click!">signal</a>

Тъй като компонентите са отделни единици за многократна употреба, които не трябва да имат никаква връзка с околните презентатори, препратките работят по малко по-различен начин. Атрибутът Latte n:href и тагът {link}, както и методите на компонентите, като например link() и други, винаги третират целта като име на сигнал. Затова не е необходимо да използвате възклицателен знак:

<a n:href="click">сигнал, не действие</a>

Ако искаме да направим препратка към презентаторите в шаблона на компонента, използваме тага {plink}:

<a href={plink Home:default}>главная страница</a>

или в кода

$this->getPresenter()->link('Home:default')

Псевдоними

Понякога е полезно да зададете лесно запомнящ се псевдоним на двойка презентатор:действие. Например, можете да наречете началната страница Front:Home:default просто home или Admin:Dashboard:default – admin.

Псевдонимите се дефинират в конфигурацията под ключа application › aliases:

application:
    aliases:
        home: Front:Home:default
        admin: Admin:Dashboard:default
        sign: Front:Sign:in

Във връзките те се записват с помощта на символа at, например:

<a n:href="@admin">administration</a>

Те се поддържат във всички методи, които работят с връзки, като например redirect() и други подобни.

Може да се случи да създадем невалидна препратка – или защото препраща към несъществуващ презентатор, или защото предава повече параметри, отколкото целевият метод получава в сигнатурата си, или когато не може да бъде генериран URL адрес за целевото действие. Какво да се прави с невалидните препратки се определя от статичната променлива Presenter::$invalidLinkMode. Тя може да има една от тези стойности (константи):

  • Presenter::InvalidLinkSilent – безшумен режим, връща символа # като URL
  • Presenter::InvalidLinkWarning – връща се съобщение E_USER_WARNING
  • Presenter::InvalidLinkTextual – визуално предупреждение, текстът на грешката се показва в линка
  • Presenter::InvalidLinkException – Хвърлено е изключение InvalidLinkException

Настройката по подразбиране е InvalidLinkWarning в производствен режим и InvalidLinkWarning | InvalidLinkTextual в режим на разработка. InvalidLinkWarning няма да убие скрипта в производствена среда, но ще се регистрира предупреждение. В средата за разработка Tracy ще улови предупреждението и ще покаже синя страница за грешка. Ако е зададен InvalidLinkTextual, водещият и компонентите ще върнат съобщение за грешка под формата на URL адрес, който е маркиран като #error:. За да направим такива връзки видими, можем да добавим CSS правило към нашия набор от стилове:

a[href^="#error:"] {
	background: red;
	color: white;
}

Ако не искаме да се генерират предупреждения в средата за разработка, можем да активираме автоматичния режим на невалидна връзка в конфигурацията.

application:
	silentLinks: true

LinkGenerator

Как да създавате връзки така удобно, както с метода link(), но без презентатора? За тази цел разполагаме с Nette\Application\LinkGenerator.

LinkGenerator е услуга, която може да се подаде през конструктора и след това да се създадат връзки чрез метода ‚link()‘.

Има разлика в сравнение с водещите. LinkGenerator създава всички връзки като абсолютни URL адреси. Освен това няма „текущ презентатор“, така че не можете да зададете само името на действието „link(‚default‘)“ или относителни пътища към модули.

Невалидните връзки винаги хвърлят изключение Nette\Application\UI\InvalidLinkException.