Crearea de legături URL

Crearea de linkuri în Nette este la fel de simplă ca și cum ați arăta cu degetul. Trebuie doar să arătați cu degetul, iar cadrul va face toată munca în locul dumneavoastră. Vă vom arăta:

  • cum să creați legături în șabloane și în alte părți
  • cum să distingem un link de pagina curentă
  • ce se întâmplă cu legăturile invalide

Datorită rutei bidirecționale, nu va trebui niciodată să codificați URL-urile aplicațiilor în șabloane sau în cod, care se pot schimba ulterior sau pot fi complicate de compus. Trebuie doar să specificați prezentatorul și acțiunea în link, să treceți orice parametru, iar framework-ul va genera singur URL-ul. De fapt, este foarte asemănător cu apelarea unei funcții. Vă va plăcea.

În șablonul de prezentator

De cele mai multe ori creăm linkuri în șabloane, iar un mare ajutor este atributul n:href:

<a n:href="Product:show">detail</a>

Rețineți că, în loc de atributul HTML href, am folosit n:attribute n:href. Valoarea acestuia nu este un URL, așa cum sunteți obișnuiți cu atributul href, ci numele prezentatorului și acțiunea.

A face clic pe un link este, pur și simplu, ceva de genul apelării unei metode ProductPresenter::renderShow(). Iar dacă aceasta are parametri în semnătura sa, o putem apela cu argumente:

<a n:href="Product:show $product->id, $product->slug">detail</a>

De asemenea, este posibil să se treacă parametri numiți. Următoarea legătură trece parametrul lang cu valoarea en:

<a n:href="Product:show $product->id, lang: en">detail</a>

În cazul în care metoda ProductPresenter::renderShow() nu are $lang în semnătura sa, aceasta poate prelua valoarea parametrului folosind $lang = $this->getParameter('lang') sau din proprietate.

În cazul în care parametrii sunt stocați într-o matrice, aceștia pot fi dezvoltați cu operatorul ... (sau cu operatorul (expand) în Latte 2.x):

{var $args = [$product->id, lang => en]}
<a n:href="Product:show ...$args">detail</a>

Așa-numiții parametri persistenți sunt, de asemenea, trecuți automat în legături.

Atributul n:href este foarte util pentru etichetele HTML <a>. Dacă dorim să imprimăm link-ul în altă parte, de exemplu în text, folosim {link}:

URL is: {link Home:default}

În cod

Metoda link() este utilizată pentru a crea o legătură în prezentator:

$url = $this->link('Product:show', $product->id);

Parametrii pot fi, de asemenea, trecuți ca o matrice în care pot fi specificați și parametri cu nume:

$url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);

Legăturile pot fi create și fără un prezentator, utilizând LinkGenerator și metoda sa link().

În cazul în care ținta legăturii este prezentatorul și acțiunea, aceasta are următoarea sintaxă:

[//] [[[[:]module:]presenter:]action | this] [#fragment]

Formatul este acceptat de toate etichetele Latte și de toate metodele presenter 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 se folosește n:href, ar putea exista oricare dintre aceste funcții.

Forma de bază este, prin urmare, Presenter:action:

<a n:href="Home:default">home</a>

Dacă facem legătura cu acțiunea prezentatorului curent, putem omite numele acestuia:

<a n:href="default">home</a>

Dacă acțiunea este default, putem omite numele, dar trebuie să păstrăm două puncte:

<a n:href="Home:">home</a>

Legăturile pot indica și alte module. Aici, legăturile se disting în relative la submodule sau absolute. Principiul este analog cu cel al căilor de acces pe disc, doar că în loc de bară oblică se folosesc două puncte. Să presupunem că actualul prezentator face parte din modulul Front, atunci vom scrie:

<a n:href="Shop:Product:show">link to Front:Shop:Product:show</a>
<a n:href=":Admin:Product:show">link to Admin:Product:show</a>

Un caz special este legătura către sine. Aici vom scrie this ca țintă.

<a n:href="this">refresh</a>

Putem crea o legătură către o anumită parte a paginii HTML prin intermediul unui așa-numit fragment după simbolul hash #:

<a n:href="Home:#main">link to Home:default and fragment #main</a>

Căi de acces absolute

Legăturile generate de link() sau n:href sunt întotdeauna căi de acces absolute (adică încep cu /), dar nu și URL-uri absolute cu un protocol și domeniu, cum ar fi https://domain.

Pentru a genera o adresă URL absolută, adăugați două bariere la început (de exemplu, n:href="//Home:"). Sau puteți comuta prezentatorul pentru a genera numai link-uri absolute, setând $this->absoluteUrls = true.

Obiectivul this va crea un link către pagina curentă:

<a n:href="this">refresh</a>

În același timp, toți parametrii specificați în semnătura de la render<View>() sau action<Action>() sunt transferați. Astfel, dacă ne aflăm pe paginile Product:show și id:123, legătura către this va transfera și acest parametru.

Desigur, este posibil să se specifice parametrii direct:

<a n:href="this refresh: 1">refresh</a>

Funcția isLinkCurrent() determină dacă ținta linkului este aceeași cu pagina curentă. Acest lucru poate fi utilizat, de exemplu, într-un șablon pentru a diferenția legăturile etc.

Parametrii sunt aceiași ca pentru metoda link(), dar este posibilă și utilizarea caracterului wildcard * în locul unei acțiuni specifice, ceea ce înseamnă orice acțiune a prezentatorului.

{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>

O formă prescurtată poate fi utilizată în combinație cu n:href într-un singur element:

<a n:class="isLinkCurrent() ? active" n:href="Product:detail">...</a>

Caracterul wildcard * înlocuiește doar acțiunea prezentatorului, nu și prezentatorul însuși.

Pentru a afla dacă ne aflăm într-un anumit modul sau într-un submodul al acestuia, putem utiliza funcția isModuleCurrent(moduleName).

<li n:class="isModuleCurrent('MyEshop:Users') ? active">
	<a n:href="Product:">...</a>
</li>

Ținta legăturii poate fi nu numai prezentatorul și acțiunea, ci și semnalul (acestea apelează metoda handle<Signal>()). Sintaxa este următoarea:

[//] [sub-component:]signal! [#fragment]

Semnalul se distinge astfel prin semnul exclamării:

<a n:href="click!">signal</a>

De asemenea, puteți crea o legătură către semnalul subcomponentei (sau sub-componentei):

<a n:href="componentName:click!">signal</a>

Deoarece componentele sunt unități separate reutilizabile care nu ar trebui să aibă relații cu prezentatorii din jur, legăturile funcționează puțin diferit. Atributul Latte n:href și tag-ul {link} și metodele componentelor, cum ar fi link() și altele, consideră întotdeauna ținta ca nume de semnal. Prin urmare, nu este necesar să se utilizeze un semn de exclamare:

<a n:href="click">signal, not an action</a>

Dacă dorim să facem legătura cu prezentatorii din șablonul componentei, folosim eticheta {plink}:

<a href="{plink Home:default}">home</a>

sau în cod

$this->getPresenter()->link('Home:default')

Se poate întâmpla să creăm o legătură invalidă – fie pentru că se referă la un prezentator inexistent, fie pentru că trece mai mulți parametri decât primește metoda țintă în semnătura sa, fie când nu poate exista un URL generat pentru acțiunea vizată. Ce trebuie făcut cu legăturile invalide este determinat de variabila statică Presenter::$invalidLinkMode. Aceasta poate avea una dintre aceste valori (constante):

  • Presenter::InvalidLinkSilent – mod silențios, returnează simbolul # ca URL.
  • Presenter::InvalidLinkWarning – se va produce E_USER_WARNING
  • Presenter::InvalidLinkTextual – avertizare vizuală, textul erorii este afișat în legătură
  • Presenter::InvalidLinkException – se va produce InvalidLinkException

Configurația implicită în modul de producție este InvalidLinkWarning, iar în modul de dezvoltare este InvalidLinkWarning | InvalidLinkTextual. InvalidLinkWarning nu omoară scriptul în mediul de producție, dar avertismentul va fi înregistrat. În mediul de dezvoltare, Tracy va intercepta avertismentul și va afișa ecranul albastru de eroare. Dacă InvalidLinkTextual este setat, prezentatorul și componentele returnează mesajul de eroare ca URL care începe cu #error:. Pentru a face vizibile astfel de linkuri, putem adăuga o regulă CSS la foaia noastră de stil:

a[href^="#error:"] {
	background: red;
	color: white;
}

Dacă nu dorim ca avertismentele să fie produse în mediul de dezvoltare, putem activa modul silent invalid link mode în configurație.

application:
	silentLinks: true

LinkGenerator

Cum se pot crea legături cu metoda link() comfort, dar fără prezența unui prezentator? De aceea, iată Nette\Application\LinkGenerator.

LinkGenerator este un serviciu pe care îl puteți avea trecut prin constructor și apoi să creați link-uri folosind metoda sa link().

Există o diferență față de prezentatori. LinkGenerator creează toate legăturile ca URL-uri absolute. În plus, nu există un “prezentator curent”, deci nu este posibil să se specifice doar numele acțiunii link('default') sau căile relative către module.

Legăturile invalide aruncă întotdeauna Nette\Application\UI\InvalidLinkException.

versiune: 4.0