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 skripta
  • Presenter::InvalidLinkTextual – vizualno opozorilo, napako izpiše neposredno v povezavo
  • Presenter::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.

različica: 4.0