Crearea linkurilor URL
Crearea linkurilor în Nette este simplă, ca și cum ai arăta cu degetul. Trebuie doar să țintești și framework-ul va face toată munca pentru tine. Vom arăta:
- cum să creezi linkuri în șabloane și în altă parte
- cum să distingi un link către pagina curentă
- ce să faci cu linkurile invalide
Datorită rutării bidirecționale, nu va trebui niciodată să scrieți manual adresele URL ale aplicației dvs. în șabloane sau cod, adrese care s-ar putea schimba ulterior, sau să le compuneți complicat. În link este suficient să specificați presenterul și acțiunea, să transmiteți eventualii parametri și framework-ul va genera URL-ul singur. De fapt, este foarte asemănător cu apelarea unei funcții. Acest lucru vă va plăcea.
În șablonul presenterului
Cel mai adesea creăm linkuri în șabloane, iar un ajutor excelent este atributul n:href
:
<a n:href="Product:show">detaliu</a>
Observați că în loc de atributul HTML href
, am folosit n:atributul n:href
. Valoarea sa nu este apoi URL-ul, așa
cum ar fi în cazul atributului href
, ci numele presenterului și al acțiunii.
Click-ul pe link este, simplificat spus, ceva asemănător cu apelarea metodei ProductPresenter::renderShow()
. Și
dacă are parametri în semnătura sa, o putem apela cu argumente:
<a n:href="Product:show $product->id, $product->slug">detaliu produs</a>
Este posibil să se transmită și parametri numiți. Următorul link transmite parametrul lang
cu valoarea
cs
:
<a n:href="Product:show $product->id, lang: cs">detaliu produs</a>
Dacă metoda ProductPresenter::renderShow()
nu are $lang
în semnătura sa, poate afla valoarea
parametrului folosind $lang = $this->getParameter('lang')
sau din proprietate.
Dacă parametrii sunt stocați într-un array, aceștia pot fi expandați cu operatorul ...
(în Latte 2.x cu
operatorul (expand)
):
{var $args = [$product->id, lang => cs]}
<a n:href="Product:show ...$args">detaliu produs</a>
În linkuri se transmit automat și așa-numiții parametri persistenți.
Atributul n:href
este foarte util pentru tag-urile HTML <a>
. Dacă dorim să afișăm linkul
în altă parte, de exemplu în text, folosim {link}
:
Adresa este: {link Home:default}
În cod
Pentru a crea un link în presenter se folosește metoda link()
:
$url = $this->link('Product:show', $product->id);
Parametrii pot fi transmiși și printr-un array, unde se pot specifica și parametri numiți:
$url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
Linkurile pot fi create și fără presenter, pentru asta există LinkGenerator și metoda sa
link()
.
Linkuri către presenter
Dacă ținta linkului este un presenter și o acțiune, are această sintaxă:
[//] [[[[:]module:]presenter:]action | this] [#fragment]
Formatul este suportat de toate tag-urile Latte și toate metodele presenterului care lucrează cu linkuri, adică
n:href
, {link}
, {plink}
, link()
, lazyLink()
,
isLinkCurrent()
, redirect()
, redirectPermanent()
, forward()
,
canonicalize()
și, de asemenea, LinkGenerator. Deci, chiar dacă în exemple este
folosit n:href
, ar putea fi oricare dintre funcții.
Forma de bază este deci Presenter:action
:
<a n:href="Home:default">pagina principală</a>
Dacă facem referire la acțiunea presenterului curent, putem omite numele acestuia:
<a n:href="default">pagina principală</a>
Dacă ținta este acțiunea default
, o putem omite, dar două puncte trebuie să rămână:
<a n:href="Home:">pagina principală</a>
Linkurile pot, de asemenea, să direcționeze către alte module. Aici, linkurile se disting
între cele relative către un submodul imbricat și cele absolute. Principiul este analog cu căile de pe disc, doar că în loc
de slash-uri sunt două puncte. Presupunem că presenterul curent face parte din modulul Front
, atunci scriem:
<a n:href="Shop:Product:show">link către Front:Shop:Product:show</a>
<a n:href=":Admin:Product:show">link către Admin:Product:show</a>
Un caz special este linkul către sine însuși, când specificăm
this
ca țintă.
<a n:href="this">refresh</a>
Putem face referire la o anumită parte a paginii prin așa-numitul fragment după semnul diez #
:
<a n:href="Home:#main">link către Home:default și fragmentul #main</a>
Căi absolute
Linkurile generate folosind link()
sau n:href
sunt întotdeauna căi absolute (adică încep cu
caracterul /
), dar nu URL-uri absolute cu protocol și domeniu precum https://domain
.
Pentru a genera un URL absolut, adăugați două slash-uri la început (de ex. n:href="//Home:"
). Sau puteți
comuta presenterul să genereze doar linkuri absolute setând $this->absoluteUrls = true
.
Link către pagina curentă
Ținta this
creează un link către pagina curentă:
<a n:href="this">refresh</a>
În același timp, se transmit și toți parametrii specificați în semnătura metodei action<Action>()
sau
render<View>()
, dacă action<Action>()
nu este definită. Deci, dacă suntem pe pagina
Product:show
și id: 123
, linkul către this
va transmite și acest parametru.
Desigur, este posibil să specificați parametrii direct:
<a n:href="this refresh: 1">refresh</a>
Funcția isLinkCurrent()
verifică dacă ținta linkului este identică cu pagina curentă. Acest lucru poate fi
utilizat, de exemplu, în șablon pentru a distinge linkurile etc.
Parametrii sunt aceiași ca la metoda link()
, dar în plus este posibil să se specifice un wildcard
*
în loc de o acțiune specifică, ceea ce înseamnă orice acțiune a presenterului respectiv.
{if !isLinkCurrent('Admin:login')}
<a n:href="Admin:login">Conectați-vă</a>
{/if}
<li n:class="isLinkCurrent('Product:*') ? active">
<a n:href="Product:">...</a>
</li>
În combinație cu n:href
într-un singur element, se poate folosi o formă prescurtată:
<a n:class="isLinkCurrent() ? active" n:href="Home:">...</a>
Wildcard-ul *
poate fi folosit doar în locul acțiunii, nu și al presenterului.
Pentru a verifica dacă ne aflăm într-un anumit modul sau submodul al acestuia, folosim metoda
isModuleCurrent(moduleName)
.
<li n:class="isModuleCurrent('Forum:Users') ? active">
<a n:href="Product:">...</a>
</li>
Linkuri către semnal
Ținta linkului nu trebuie să fie doar un presenter și o acțiune, ci și un semnal (apelează metoda
handle<Signal>()
). Atunci sintaxa este următoarea:
[//] [sub-component:]signal! [#fragment]
Semnalul este deci distins prin semnul exclamării:
<a n:href="click!">semnal</a>
Se poate crea și un link către semnalul unei subcomponente (sau sub-subcomponente):
<a n:href="componentName:click!">semnal</a>
Linkuri în componentă
Deoarece componentele sunt unități separate, reutilizabile,
care nu ar trebui să aibă nicio legătură cu presenterele din jur, linkurile funcționează aici puțin diferit. Atributul
Latte n:href
și tag-ul {link}
, precum și metodele componentei precum link()
și altele
consideră ținta linkului întotdeauna ca fiind numele semnalului. De aceea, nu este necesar nici măcar să se specifice
semnul exclamării:
<a n:href="click">semnal, nu acțiune</a>
Dacă am dori să facem referire la presentere în șablonul componentei, folosim tag-ul {plink}
:
<a href={plink Home:default}>introducere</a>
sau în cod
$this->getPresenter()->link('Home:default')
Aliasuri
Uneori poate fi util să atribuiți perechii Presenter:acțiune un alias ușor de reținut. De exemplu, pagina de start
Front:Home:default
să o numiți simplu home
sau Admin:Dashboard:default
ca
admin
.
Aliasurile se definesc în configurație sub cheia
application › aliases
:
application:
aliases:
home: Front:Home:default
admin: Admin:Dashboard:default
sign: Front:Sign:in
În linkuri se scriu apoi folosind arondul, de exemplu:
<a n:href="@admin">administrare</a>
Sunt suportate și în toate metodele care lucrează cu linkuri, cum ar fi redirect()
și altele asemenea.
Linkuri invalide
Se poate întâmpla să creăm un link invalid – fie pentru că duce la un presenter inexistent, fie pentru că transmite
mai mulți parametri decât acceptă metoda țintă în semnătura sa, sau când nu se poate genera un URL pentru acțiunea
țintă. Cum să tratăm linkurile invalide este determinat de variabila statică Presenter::$invalidLinkMode
.
Aceasta poate lua o combinație a acestor valori (constante):
Presenter::InvalidLinkSilent
– mod silențios, ca URL se returnează caracterul #Presenter::InvalidLinkWarning
– se aruncă o avertizare E_USER_WARNING, care va fi înregistrată în modul de producție, dar nu va cauza întreruperea execuției scriptuluiPresenter::InvalidLinkTextual
– avertizare vizuală, afișează eroarea direct în linkPresenter::InvalidLinkException
– se aruncă excepția InvalidLinkException
Setarea implicită este InvalidLinkWarning
în modul de producție și
InvalidLinkWarning | InvalidLinkTextual
în modul de dezvoltare. InvalidLinkWarning
în mediul de
producție nu cauzează întreruperea scriptului, dar avertizarea va fi înregistrată. În mediul de dezvoltare, Tracy o va captura și va afișa un bluescreen. InvalidLinkTextual
funcționează astfel încât returnează ca URL un mesaj de eroare care începe cu caracterele #error:
. Pentru ca
astfel de linkuri să fie vizibile la prima vedere, adăugăm în CSS:
a[href^="#error:"] {
background: red;
color: white;
}
Dacă nu dorim să se producă avertizări în mediul de dezvoltare, putem seta modul silențios direct în configurație.
application:
silentLinks: true
LinkGenerator
Cum să creăm linkuri cu un confort similar cu cel al metodei link()
, dar fără prezența unui presenter? Pentru
asta există Nette\Application\LinkGenerator.
LinkGenerator este un serviciu pe care îl puteți primi prin constructor și apoi crea linkuri folosind metoda sa
link()
.
Spre deosebire de presentere, există o diferență. LinkGenerator creează toate linkurile direct ca URL-uri absolute. Și,
în plus, nu există niciun “presenter curent”, deci nu se poate specifica doar numele acțiunii link('default')
ca țintă sau specifica căi relative către module.
Linkurile invalide aruncă întotdeauna Nette\Application\UI\InvalidLinkException
.