Ustvarjanje URL povezav
Ustvarjanje povezav v Nette je preprosto, kot kazanje s prstom. Dovolj je le nameriti in ogrodje bo že samo opravilo vse delo. Pokazali si bomo:
- kako ustvarjati povezave v predlogah in drugje
- kako razlikovati povezavo na trenutno stran
- kaj storiti z neveljavnimi povezavami
Zahvaljujoč dvosmernemu usmerjanju vam nikoli ne bo treba v predloge ali kodo trdo kodirati URL naslovov vaše aplikacije, ki se lahko kasneje spremenijo, ali jih zapleteno sestavljati. V povezavi je dovolj navesti presenter in akcijo, posredovati morebitne parametre in ogrodje bo že samo generiralo URL. Pravzaprav je to zelo podobno, kot ko kličete funkcijo. To vam bo všeč.
V predlogi presenterja
Najpogosteje ustvarjamo povezave v predlogah in odličen pomočnik je atribut n:href:
<a n:href="Product:show">podrobnosti</a>
Opazite, da smo namesto HTML atributa href uporabili n:atribut n:href. Njegova vrednost potem ni URL, kot bi
bilo v primeru atributa href, ampak ime presenterja in akcije.
Klik na povezavo je, poenostavljeno rečeno, nekaj takega kot klicanje metode ProductPresenter::renderShow(). In
če ima v svoji signaturi parametre, jo lahko kličemo z argumenti:
<a n:href="Product:show $product->id, $product->slug">podrobnosti izdelka</a>
Možno je posredovati tudi imenovane parametre. Naslednja povezava posreduje parameter lang z vrednostjo
cs:
<a n:href="Product:show $product->id, lang: cs">podrobnosti izdelka</a>
Če metoda ProductPresenter::renderShow() nima $lang v svoji signaturi, lahko vrednost parametra
ugotovi s pomočjo $lang = $this->getParameter('lang') ali iz lastnosti.
Če so parametri shranjeni v polju, jih lahko razvijemo z operatorjem ... (v Latte 2.x z operatorjem
(expand)):
{var $args = [$product->id, lang => cs]}
<a n:href="Product:show ...$args">podrobnosti izdelka</a>
V povezavah se samodejno prenašajo tudi t.i. persistentni parametri.
Atribut n:href je zelo priročen za HTML značke <a>. Če želimo povezavo izpisati drugje, na
primer v besedilu, uporabimo {link}:
Naslov je: {link Home:default}
V kodi
Za ustvarjanje povezave v presenterju služi metoda link():
$url = $this->link('Product:show', $product->id);
Parametre lahko posredujemo tudi s pomočjo polja, kjer lahko navedemo tudi imenovane parametre:
$url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Povezave lahko ustvarjamo tudi brez presenterja, za to je tu LinkGenerator in njegova metoda
link().
Povezave na presenter
Če je cilj povezave presenter in akcija, ima to sintakso:
[//] [[[[:]module:]presenter:]action | this] [#fragment]
Format podpirajo vse značke Latte in vse metode presenterja, ki delajo s povezavami, torej n:href,
{link}, {plink}, link(), lazyLink(), isLinkCurrent(),
redirect(), redirectPermanent(), forward(), canonicalize() in tudi LinkGenerator. Torej, čeprav je v primerih uporabljen n:href, bi lahko bila tam
katerakoli od funkcij.
Osnovna oblika je torej Presenter:action:
<a n:href="Home:default">domača stran</a>
Če povezujemo na akcijo trenutnega presenterja, lahko njegovo ime izpustimo:
<a n:href="default">domača stran</a>
Če je cilj akcija default, jo lahko izpustimo, vendar dvopičje mora ostati:
<a n:href="Home:">domača stran</a>
Povezave lahko vodijo tudi v druge module. Tukaj se povezave
razlikujejo na relativne v ugnezden podmodul ali absolutne. Princip je analogen potem na disku, le da so namesto poševnic
dvopičja. Predpostavimo, da je trenutni presenter del modula Front, potem zapišemo:
<a n:href="Shop:Product:show">povezava na Front:Shop:Product:show</a>
<a n:href=":Admin:Product:show">povezava na Admin:Product:show</a>
Poseben primer je povezava nase, ko kot cilj navedemo this.
<a n:href="this">osveži</a>
Povezovati lahko na določen del strani prek t.i. fragmenta za znakom lojtre #:
<a n:href="Home:#main">povezava na Home:default in fragment #main</a>
Absolutne poti
Povezave, generirane s pomočjo link() ali n:href, so vedno absolutne poti (tj. začnejo se
z znakom /), vendar ne absolutni URL-ji s protokolom in domeno kot https://domain.
Za generiranje absolutnega URL-ja dodajte na začetek dve poševnici (npr. n:href="//Home:"). Ali pa lahko
preklopite presenter, da generira samo absolutne povezave z nastavitvijo $this->absoluteUrls = true.
Povezava na trenutno stran
Cilj this ustvari povezavo na trenutno stran:
<a n:href="this">osveži</a>
Hkrati se prenašajo tudi vsi parametri, navedeni v signaturi metode action<Action>() ali
render<View>(), če action<Action>() ni definirana. Torej, če smo na strani
Product:show in id: 123, povezava na this prenese tudi ta parameter.
Seveda je mogoče parametre specificirati neposredno:
<a n:href="this refresh: 1">osveži</a>
Funkcija isLinkCurrent() ugotavlja, ali je cilj povezave enak trenutni strani. To lahko uporabimo na primer
v predlogi za razlikovanje povezav ipd.
Parametri so enaki kot pri metodi link(), poleg tega pa je mogoče namesto konkretne akcije navesti nadomestni
znak *, ki pomeni katerokoli akcijo danega presenterja.
{if !isLinkCurrent('Admin:login')}
<a n:href="Admin:login">Prijavite se</a>
{/if}
<li n:class="isLinkCurrent('Product:*') ? active">
<a n:href="Product:">...</a>
</li>
V kombinaciji z n:href v enem elementu se da uporabiti skrajšana oblika:
<a n:class="isLinkCurrent() ? active" n:href="Home:">...</a>
Nadomestni znak * lahko uporabimo samo namesto akcije, ne pa presenterja.
Za ugotavljanje, ali smo v določenem modulu ali njegovem podmodulu, uporabimo metodo
isModuleCurrent(moduleName).
<li n:class="isModuleCurrent('Forum:Users') ? active">
<a n:href="Product:">...</a>
</li>
Povezave na signal
Cilj povezave ni nujno samo presenter in akcija, ampak tudi signal (kličejo metodo
handle<Signal>()). Potem je sintaksa naslednja:
[//] [sub-component:]signal! [#fragment]
Signal torej loči klicaj:
<a n:href="click!">signal</a>
Lahko ustvarimo tudi povezavo na signal podkomponente (ali pod-podkomponente):
<a n:href="componentName:click!">signal</a>
Povezave v komponenti
Ker so komponente samostojne ponovno uporabne enote, ki ne bi
smele imeti nobenih povezav z okoliškimi presenterji, tukaj povezave delujejo nekoliko drugače. Atribut Latte
n:href in značka {link} ter metode komponent, kot je link() in druge, obravnavajo cilj
povezave vedno kot ime signala. Zato ni treba niti navajati klicaja:
<a n:href="click">signal, ne akcija</a>
Če bi želeli v predlogi komponente povezovati na presenterje, uporabimo za to značko {plink}:
<a href={plink Home:default}>domov</a>
ali v kodi
$this->getPresenter()->link('Home:default')
Aliasi
Včasih se lahko zgodi, da je koristno paru Presenter:akcija dodeliti lahko zapomnljiv alias. Na primer, domačo stran
Front:Home:default poimenovati preprosto kot home ali Admin:Dashboard:default kot
admin.
Aliasi se definirajo v konfiguraciji pod ključem
application › aliases:
application:
aliases:
home: Front:Home:default
admin: Admin:Dashboard:default
sign: Front:Sign:in
V povezavah se nato zapisujejo s pomočjo afne, na primer:
<a n:href="@admin">administracija</a>
Podprti so tudi v vseh metodah, ki delajo s povezavami, kot je redirect() in podobno.
Neveljavne povezave
Lahko se zgodi, da ustvarimo neveljavno povezavo – bodisi zato, ker vodi na neobstoječ presenter, ali zato, ker posreduje
več parametrov, kot jih ciljna metoda sprejema v svoji signaturi, ali ko za ciljno akcijo ni mogoče generirati URL-ja. Kako
ravnati z neveljavnimi povezavami, določa statična spremenljivka Presenter::$invalidLinkMode. Ta lahko prevzame
kombinacijo teh vrednosti (konstant):
Presenter::InvalidLinkSilent– tihi način, kot URL se vrne znak #Presenter::InvalidLinkWarning– sproži se opozorilo E_USER_WARNING, ki bo v produkcijskem načinu zabeleženo, vendar ne bo povzročilo prekinitve izvajanja skriptaPresenter::InvalidLinkTextual– vizualno opozorilo, napako izpiše neposredno v povezavoPresenter::InvalidLinkException– sproži se izjema InvalidLinkException
Privzeta nastavitev je InvalidLinkWarning v produkcijskem načinu in
InvalidLinkWarning | InvalidLinkTextual v razvojnem. InvalidLinkWarning v produkcijskem okolju ne
povzroči prekinitve skripta, vendar bo opozorilo zabeleženo. V razvojnem okolju ga ujame Tracy in prikaže bluescreen. InvalidLinkTextual deluje tako, da kot URL vrne
sporočilo o napaki, ki se začne z znaki #error:. Da bi bile takšne povezave na prvi pogled očitne, si dodamo
v CSS:
a[href^="#error:"] {
background: red;
color: white;
}
Če ne želimo, da se v razvojnem okolju producirajo opozorila, lahko nastavimo tihi način neposredno v konfiguraciji.
application:
silentLinks: true
LinkGenerator
Kako ustvarjati povezave s podobnim udobjem kot ima metoda link(), vendar brez prisotnosti presenterja? Za to je
tu Nette\Application\LinkGenerator.
LinkGenerator je storitev, ki si jo lahko pustite posredovati prek konstruktorja in nato ustvarjate povezave z njegovo metodo
link().
V primerjavi s presenterji je tu razlika. LinkGenerator ustvarja vse povezave takoj kot absolutne URL-je. In nadalje ne
obstaja noben “trenutni presenter”, zato ni mogoče kot cilj navesti samo ime akcije link('default') ali navajati
relativne poti do modulov.
Neveljavne povezave vedno sprožijo Nette\Application\UI\InvalidLinkException.