Creazione di link URL

Creare link in Nette è semplice come puntare il dito. Basta mirare e il framework farà tutto il lavoro per te. Vedremo:

  • come creare link nei template e altrove
  • come distinguere un link alla pagina corrente
  • cosa fare con i link non validi

Grazie al routing bidirezionale, non dovrai mai scrivere hardcoded gli indirizzi URL della tua applicazione nei template o nel codice, che potrebbero cambiare in seguito, o comporli in modo complicato. Nel link, basta specificare il presenter e l'azione, passare eventuali parametri e il framework genererà l'URL da solo. In realtà, è molto simile a chiamare una funzione. Ti piacerà.

Nel template del presenter

Il più delle volte creiamo link nei template e un ottimo aiuto è l'attributo n:href:

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

Nota che invece dell'attributo HTML href, abbiamo usato l'attributo n n:href. Il suo valore non è quindi un URL, come sarebbe nel caso dell'attributo href, ma il nome del presenter e dell'azione.

Cliccare sul link è, in parole povere, qualcosa come chiamare il metodo ProductPresenter::renderShow(). E se ha parametri nella sua firma, possiamo chiamarlo con argomenti:

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

È possibile passare anche parametri nominati. Il seguente link passa il parametro lang con il valore cs:

<a n:href="Product:show $product->id, lang: cs">dettaglio prodotto</a>

Se il metodo ProductPresenter::renderShow() non ha $lang nella sua firma, può ottenere il valore del parametro usando $lang = $this->getParameter('lang') o dalla proprietà.

Se i parametri sono memorizzati in un array, possono essere espansi con l'operatore ... (in Latte 2.x con l'operatore (expand)):

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

Nei link vengono automaticamente passati anche i cosiddetti parametri persistenti.

L'attributo n:href è molto utile per i tag HTML <a>. Se vogliamo stampare il link altrove, ad esempio nel testo, usiamo {link}:

L'indirizzo è: {link Home:default}

Nel codice

Per creare un link nel presenter, si usa il metodo link():

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

I parametri possono essere passati anche tramite un array, dove è possibile specificare anche parametri nominati:

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

I link possono essere creati anche senza un presenter, per questo c'è LinkGenerator e il suo metodo link().

Se la destinazione del link è un presenter e un'azione, ha questa sintassi:

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

Il formato è supportato da tutti i tag Latte e da tutti i metodi del presenter che lavorano con i link, cioè n:href, {link}, {plink}, link(), lazyLink(), isLinkCurrent(), redirect(), redirectPermanent(), forward(), canonicalize() e anche LinkGenerator. Quindi, anche se negli esempi viene usato n:href, potrebbe esserci una qualsiasi delle funzioni.

La forma base è quindi Presenter:action:

<a n:href="Home:default">pagina iniziale</a>

Se ci colleghiamo a un'azione del presenter corrente, possiamo omettere il suo nome:

<a n:href="default">pagina iniziale</a>

Se la destinazione è l'azione default, possiamo ometterla, ma i due punti devono rimanere:

<a n:href="Home:">pagina iniziale</a>

I link possono anche puntare ad altri moduli. Qui i link si distinguono in relativi a un sottomodulo nidificato o assoluti. Il principio è analogo ai percorsi su disco, solo che al posto degli slash ci sono i due punti. Supponiamo che il presenter corrente faccia parte del modulo Front, allora scriveremo:

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

Un caso speciale è un link a se stesso, dove specifichiamo this come destinazione.

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

Possiamo collegarci a una parte specifica della pagina tramite il cosiddetto frammento dopo il simbolo cancelletto #:

<a n:href="Home:#main">link a Home:default e frammento #main</a>

Percorsi assoluti

I link generati usando link() o n:href sono sempre percorsi assoluti (cioè iniziano con /), ma non URL assoluti con protocollo e dominio come https://domain.

Per generare un URL assoluto, aggiungi due slash all'inizio (es. n:href="//Home:"). Oppure si può impostare il presenter per generare solo link assoluti impostando $this->absoluteUrls = true.

La destinazione this crea un link alla pagina corrente:

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

Allo stesso tempo, vengono trasferiti anche tutti i parametri specificati nella firma del metodo action<Action>() o render<View>(), se action<Action>() non è definita. Quindi, se siamo sulla pagina Product:show e id: 123, il link a this passerà anche questo parametro.

Ovviamente, è possibile specificare i parametri direttamente:

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

La funzione isLinkCurrent() verifica se la destinazione del link è identica alla pagina corrente. Questo può essere utilizzato, ad esempio, nel template per distinguere i link, ecc.

I parametri sono gli stessi del metodo link(), ma è anche possibile specificare un carattere jolly * invece di un'azione specifica, che significa qualsiasi azione del presenter dato.

{if !isLinkCurrent('Admin:login')}
	<a n:href="Admin:login">Accedi</a>
{/if}

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

In combinazione con n:href in un unico elemento, si può usare la forma abbreviata:

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

Il carattere jolly * può essere usato solo al posto dell'azione, non del presenter.

Per verificare se siamo in un certo modulo o in un suo sottomodulo, usiamo il metodo isModuleCurrent(moduleName).

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

La destinazione di un link non deve essere solo un presenter e un'azione, ma anche un segnale (chiamano il metodo handle<Signal>()). Allora la sintassi è la seguente:

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

Il segnale è quindi distinto dal punto esclamativo:

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

È possibile creare anche un link al segnale di un sottocomponente (o sotto-sottocomponente):

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

Poiché i componenti sono unità riutilizzabili separate che non dovrebbero avere legami con i presenter circostanti, i link funzionano in modo leggermente diverso qui. L'attributo Latte n:href e il tag {link} così come i metodi del componente come link() e altri considerano la destinazione del link sempre come il nome del segnale. Pertanto, non è nemmeno necessario specificare il punto esclamativo:

<a n:href="click">segnale, non azione</a>

Se volessimo collegarci ai presenter nel template del componente, useremmo il tag {plink}:

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

o nel codice

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

Alias

A volte può essere utile assegnare un alias facilmente memorizzabile alla coppia Presenter:azione. Ad esempio, chiamare la pagina iniziale Front:Home:default semplicemente home o Admin:Dashboard:default come admin.

Gli alias sono definiti nella configurazione sotto la chiave application › aliases:

application:
    aliases:
        home: Front:Home:default
        admin: Admin:Dashboard:default
        sign: Front:Sign:in

Nei link, vengono poi scritti usando la chiocciola, ad esempio:

<a n:href="@admin">amministrazione</a>

Sono supportati anche in tutti i metodi che lavorano con i link, come redirect() e simili.

Può capitare di creare un link non valido – sia perché punta a un presenter inesistente, sia perché passa più parametri di quelli che il metodo di destinazione accetta nella sua firma, o quando non è possibile generare un URL per l'azione di destinazione. Come gestire i link non validi è determinato dalla variabile statica Presenter::$invalidLinkMode. Può assumere una combinazione di questi valori (costanti):

  • Presenter::InvalidLinkSilent – modalità silenziosa, come URL viene restituito il carattere #
  • Presenter::InvalidLinkWarning – viene generato un avviso E_USER_WARNING, che verrà registrato in modalità produzione, ma non causerà l'interruzione dell'esecuzione dello script
  • Presenter::InvalidLinkTextual – avviso visivo, stampa l'errore direttamente nel link
  • Presenter::InvalidLinkException – viene lanciata l'eccezione InvalidLinkException

L'impostazione predefinita è InvalidLinkWarning in modalità produzione e InvalidLinkWarning | InvalidLinkTextual in modalità sviluppo. InvalidLinkWarning nell'ambiente di produzione non causerà l'interruzione dello script, ma l'avviso verrà registrato. Nell'ambiente di sviluppo, verrà catturato da Tracy e verrà visualizzato un bluescreen. InvalidLinkTextual funziona restituendo un messaggio di errore come URL, che inizia con i caratteri #error:. Per rendere tali link evidenti a prima vista, aggiungiamo al CSS:

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

Se non vogliamo che vengano prodotti avvisi nell'ambiente di sviluppo, possiamo impostare la modalità silenziosa direttamente nella configurazione.

application:
	silentLinks: true

LinkGenerator

Come creare link con una comodità simile a quella del metodo link(), ma senza la presenza di un presenter? Per questo c'è Nette\Application\LinkGenerator.

LinkGenerator è un servizio che puoi farti passare tramite il costruttore e poi creare link con il suo metodo link().

Rispetto ai presenter, c'è una differenza. LinkGenerator crea tutti i link direttamente come URL assoluti. Inoltre, non esiste un “presenter corrente”, quindi non è possibile specificare solo il nome dell'azione link('default') come destinazione o specificare percorsi relativi ai moduli.

I link non validi lanciano sempre Nette\Application\UI\InvalidLinkException.

versione: 4.0