Створення URL-посилань
Створювати посилання в Nette так само просто, як тикати пальцем. Просто наведіть курсор, і система зробить усю роботу за вас. Ми покажемо:
- як створювати посилання в шаблонах та інших місцях
- як виділити посилання на поточну сторінку
- що робити з недійсними посиланнями
Завдяки двонаправленій маршрутизації, вам ніколи не доведеться жорстко кодувати URL додатка в шаблонах або коді, які можуть змінитися пізніше або бути складними для складання. Просто вкажіть презентера і дію в посиланні, передайте будь-які параметри, і фреймворк сам згенерує URL. Фактично, це дуже схоже на виклик функції. Вам сподобається.
У шаблоні презентера
Найчастіше ми створюємо посилання в шаблонах, і чудовим помічником є
атрибут n:href
:
<a n:href="Product:show">подробнее</a>
Зверніть увагу, що замість HTML-атрибута href
ми використовували n:attribute 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>
or in the code
$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_WARNINGPresenter::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
.