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
.