Tworzenie linków URL
Tworzenie linków w Nette jest tak proste jak wskazanie palcem. Wystarczy wskazać, a framework wykona całą pracę za Ciebie. Zobaczmy:
- jak tworzyć linki w szablonach i innych miejscach
- jak wyróżnić link do bieżącej strony
- co zrobić z nieważnymi linkami
Dzięki dwukierunkowemu routingowi nigdy nie będziesz musiał pisać adresów URL aplikacji w szablonach lub kodzie, który może się zmienić lub być skomplikowany do skomponowania później. Wystarczy określić prezentera i akcję w linku, przekazać dowolne parametry, a framework sam wygeneruje adres URL. W rzeczywistości jest to bardzo podobne do wywołania funkcji. Spodoba ci się to.
W szablonie prezentera
Najczęściej tworzymy linki w szablonach i dużą pomocą jest atrybut n:href
:
<a n:href="Product:show">detail</a>
Zauważ, że zamiast atrybutu HTML href
użyliśmy atrybutu n: n:href
. Jego wartością nie jest wtedy adres URL,
jak miałoby to miejsce w przypadku atrybutu href
, ale nazwa prezentera i akcja.
Kliknięcie na link jest, najprościej mówiąc, jak wywołanie metody ProductPresenter::renderShow()
. A jeśli
ma parametry w swoim podpisie, możemy go wywołać z argumentami:
<a n:href="Product:show $product->id, $product->slug">detail produktu</a>
Możliwe jest również przekazywanie nazwanych parametrów. Poniższy link przekazuje parametr lang
z wartością cs
:
<a n:href="Product:show $product->id, lang: cs">detail produktu</a>
Jeśli metoda ProductPresenter::renderShow()
nie ma w swojej sygnaturze $lang
, może pobrać
wartość parametru za pomocą $lang = $this->getParameter('lang')
lub z właściwości.
Jeśli parametry są przechowywane w tablicy, można je rozwinąć za pomocą operatora ...
(w Latte 2.x operator
(expand)
):
{var $args = [$product->id, lang => cs]}
<a n:href="Product:show ...$args">detail produktu</a>
Tak zwane trwałe parametry są również automatycznie przekazywane w referencjach.
Atrybut n:href
jest bardzo przydatny dla znaczników HTML <a>
. Jeśli chcemy wymienić link w
innym miejscu, na przykład w tekście, używamy {link}
:
Adresa je: {link Home:default}
W kodzie
Metoda link()
służy do tworzenia linku w prezenterze:
$url = $this->link('Product:show', $product->id);
Parametry mogą być również przekazywane za pomocą tablicy, gdzie można również określić parametry nazwane:
$url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Linki można tworzyć bez prezentera, do tego służy LinkGenerator i jego metoda
link()
.
Linki do prezentera
Jeśli celem linku jest prezenter i akcja, to ma on taką składnię:
[//] [[[[:]module:]presenter:]action | this] [#fragment]
Format jest obsługiwany przez wszystkie znaczniki Latte oraz wszystkie metody prezentera, które pracują z linkami, czyli
n:href
, {link}
, {plink}
, link()
, lazyLink()
,
isLinkCurrent()
, redirect()
, redirectPermanent()
, forward()
,
canonicalize()
a także LinkGenerator. Więc nawet jeśli n:href
jest
używany w przykładach, każda z funkcji może tam być.
Podstawową formą jest więc Presenter:action
:
<a n:href="Home:default">úvodní stránka</a>
Jeśli odnosimy się do działania bieżącego prezentera, możemy pominąć nazwę prezentera:
<a n:href="default">úvodní stránka</a>
Jeśli celem działania jest default
, możemy go pominąć, ale dwukropek musi pozostać:
<a n:href="Home:">úvodní stránka</a>
Linki mogą również wskazywać na inne moduły. Tutaj linki są
rozróżniane jako względne do zagnieżdżonego podmodułu lub bezwzględne. Zasada działania jest analogiczna do ścieżek
dyskowych, ale z dwukropkami zamiast ukośników. Załóżmy, że aktualny prezenter jest częścią modułu Front
,
wtedy piszemy:
<a n:href="Shop:Product:show">odkaz na Front:Shop:Product:show</a>
<a n:href=":Admin:Product:show">odkaz na Admin:Product:show</a>
Szczególnym przypadkiem jest autoreferencja, w której jako miejsce docelowe podajemy
this
.
<a n:href="this">refresh</a>
Możemy linkować do określonej części strony poprzez fragment po znaku siatki #
:
<a n:href="Home:#main">odkaz na Home:default a fragment #main</a>
Ścieżki bezwzględne
Linki generowane przez link()
lub n:href
są zawsze ścieżkami bezwzględnymi (tj. zaczynają się
od /
), ale nie bezwzględnymi adresami URL z protokołem i domeną jak https://domain
.
Aby wygenerować bezwzględny adres URL, dodaj dwa ukośniki na początku (np. n:href="//Home:"
). Możesz też
przełączyć prezenter, aby generował tylko bezwzględne linki, ustawiając $this->absoluteUrls = true
.
Link do bieżącej strony
Cel this
tworzy link do bieżącej strony:
<a n:href="this">refresh</a>
W tym samym czasie, wszystkie parametry określone w sygnaturze parametru action<Action>()
lub
render<View>()
jeśli metoda action<Action>()
nie są zdefiniowane, są przekazywane. Jeśli
więc jesteśmy na stronach Product:show
i id:123
, link do this
również przekaże ten
parametr.
Oczywiście istnieje możliwość bezpośredniego podania parametrów:
<a n:href="this refresh: 1">refresh</a>
Funkcja isLinkCurrent()
sprawdza, czy miejsce docelowe linku jest takie samo jak bieżąca strona. Można to
wykorzystać np. w szablonie do wyróżnienia linków itp.
Parametry są takie same jak w przypadku metody link()
, ale dodatkowo można zamiast konkretnej akcji podać
symbol wieloznaczny *
, aby wskazać dowolną akcję prezentera.
{if !isLinkCurrent('Admin:login')}
<a n:href="Admin:login">Přihlaste se</a>
{/if}
<li n:class="isLinkCurrent('Product:*') ? active">
<a n:href="Product:">...</a>
</li>
Forma krótka może być stosowana w połączeniu z n:href
w jednym elemencie:
<a n:class="isLinkCurrent() ? active" n:href="Home:">...</a>
Symbol wieloznaczny *
może być użyty tylko w miejsce akcji, nie prezentera.
Aby określić, czy jesteśmy w module lub jego podmodule, używamy metody isModuleCurrent(moduleName)
.
<li n:class="isModuleCurrent('Forum:Users') ? active">
<a n:href="Product:">...</a>
</li>
Odniesienia sygnałów
Celem linku może być nie tylko prezenter i akcja, ale także sygnał (wywołują metodę
handle<Signal>()
). Wtedy składnia jest następująca:
[//] [sub-component:]signal! [#fragment]
Sygnał ten jest więc wyróżniony wykrzyknikiem:
<a n:href="click!">signal</a>
Można również utworzyć odniesienie do sygnału podrzędnego (lub podrzędnego):
<a n:href="componentName:click!">signal</a>
Odniesienia w komponencie
Ponieważ komponenty są samodzielnymi, wielokrotnego użytku
jednostkami, które nie powinny mieć żadnych powiązań z otaczającymi prezenterami, linki działają tutaj nieco inaczej.
Atrybut Latte n:href
oraz znacznik {link}
, a także metody składowe, takie jak link()
i inne, traktują cel łącza zawsze jako nazwę sygnału. Dlatego nie ma nawet potrzeby umieszczania wykrzyknika:
<a n:href="click">signál, nikoliv akce</a>
Gdybyśmy chcieli odwołać się do prezenterów w szablonie komponentu, użylibyśmy do tego celu tagu
{plink}
:
<a href={plink Home:default}>home</a>
lub w kodzie
$this->getPresenter()->link('Home:default')
Pseudonimy
Czasami przydatne jest przypisanie łatwego do zapamiętania aliasu do pary Presenter:action. Na przykład, można nazwać
stronę główną Front:Home:default
po prostu jako home
lub Admin:Dashboard:default
jako
admin
.
Aliasy są definiowane w konfiguracji pod kluczem
application › aliases
:
application:
aliases:
home: Front:Home:default
admin: Admin:Dashboard:default
sign: Front:Sign:in
W linkach są one zapisywane przy użyciu symbolu at, na przykład:
<a n:href="@admin">administration</a>
Są one obsługiwane we wszystkich metodach, które działają z linkami, takimi jak redirect()
i podobne.
Nieprawidłowe linki
Może się zdarzyć, że utworzymy nieprawidłowy link – albo dlatego, że prowadzi do nieistniejącego prezentera, albo
dlatego, że przekazuje więcej parametrów niż docelowa metoda akceptuje w swojej sygnaturze, albo gdy nie można wygenerować
adresu URL dla docelowej akcji. O tym, jak obsłużyć nieprawidłowe linki, decyduje zmienna statyczna
Presenter::$invalidLinkMode
. Może przyjmować kombinację następujących wartości (stałych):
Presenter::InvalidLinkSilent
– tryb cichy, adres URL zwróci znak #.Presenter::InvalidLinkWarning
– wyświetlane jest ostrzeżenie E_USER_WARNING, które będzie rejestrowane w trybie produkcyjnym, ale nie spowoduje przerwania skryptuPresenter::InvalidLinkTextual
– ostrzeżenie wizualne, drukuje błąd bezpośrednio do linkuPresenter::InvalidLinkException
– rzuca wyjątek InvalidLinkException
Domyślnie jest to InvalidLinkWarning
w trybie produkcyjnym i InvalidLinkWarning | InvalidLinkTextual
w trybie deweloperskim. InvalidLinkWarning
w trybie produkcyjnym nie spowoduje przerwania skryptu, ale ostrzeżenie
zostanie zapisane w dzienniku. W środowisku programistycznym Tracy złapie to
i wyświetli bluescreen. InvalidLinkTextual
działa poprzez zwrócenie komunikatu o błędzie, który zaczyna się
od #error:
jako adresu URL. Aby takie linki były widoczne na pierwszy rzut oka, dodamy trochę CSS:
a[href^="#error:"] {
background: red;
color: white;
}
Jeśli nie chcemy, aby środowisko programistyczne generowało ostrzeżenia, możemy ustawić tryb silent bezpośrednio w konfiguracji.
application:
silentLinks: true
LinkGenerator
Jak tworzyć linki z podobną wygodą jak metoda link()
, ale bez obecności prezentera? Po to właśnie jest Nette\Application\LinkGenerator.
LinkGenerator to usługa, którą można mieć przekazaną przez konstruktor, a następnie tworzyć linki za pomocą jego
metody link()
.
W porównaniu z prezenterami jest różnica. LinkGenerator tworzy wszystkie linki bezpośrednio jako bezwzględne adresy URL.
Nie ma również “rzeczywistego prezentera”, więc nie możesz po prostu podać nazwy akcji link('default')
jako
celu lub podać względnych ścieżek do modułów.
Nieważne linki zawsze wyrzucają Nette\Application\UI\InvalidLinkException
.