Creazione di collegamenti URL
Creare collegamenti in Nette è facile come puntare un dito. Basta indicare e il framework farà tutto il lavoro per voi. Vi mostreremo:
- come creare collegamenti nei template e altrove
- come distinguere un collegamento alla pagina corrente
- cosa fare con i link non validi
Grazie al routing bidirezionale, non dovrete mai codificare gli URL delle applicazioni nei template o nel codice, che potrebbero cambiare in seguito o essere complicati da comporre. Basta specificare il presentatore e l'azione nel link, passare eventuali parametri e il framework genererà da solo l'URL. In effetti, è molto simile alla chiamata di una funzione. Vi piacerà.
Nel modello del presentatore
Il più delle volte creiamo collegamenti nei modelli e un grande aiuto è l'attributo n:href
:
<a n:href="Product:show">detail</a>
Si noti che al posto dell'attributo HTML href
abbiamo usato n:attributo n:href
. Il suo valore non è un URL, come
si è abituati a vedere con l'attributo href
, ma il nome del presentatore e l'azione.
Cliccare su un link è, in parole povere, come chiamare un metodo ProductPresenter::renderShow()
. E se ha dei
parametri nella sua firma, possiamo chiamarlo con degli argomenti:
<a n:href="Product:show $product->id, $product->slug">detail</a>
È anche possibile passare parametri con nome. Il seguente collegamento passa il parametro lang
con il valore
en
:
<a n:href="Product:show $product->id, lang: en">detail</a>
Se il metodo ProductPresenter::renderShow()
non ha $lang
nella sua firma, può recuperare 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 ...
(o (expand)
in Latte 2.x):
{var $args = [$product->id, lang => en]}
<a n:href="Product:show ...$args">detail</a>
Anche i cosiddetti parametri persistenti vengono passati automaticamente nei collegamenti.
L'attributo n:href
è molto utile per i tag HTML <a>
. Se vogliamo stampare il link altrove,
per esempio nel testo, usiamo {link}
:
URL is: {link Home:default}
Nel codice
Il metodo link()
viene utilizzato per creare un collegamento nel presentatore:
$url = $this->link('Product:show', $product->id);
I parametri possono essere passati anche come array in cui possono essere specificati anche parametri denominati:
$url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);
I collegamenti possono essere creati anche senza presentatore, utilizzando il LinkGenerator e
il suo metodo link()
.
Collegamenti al presentatore
Se l'obiettivo del collegamento è il presentatore e l'azione, la sintassi è questa:
[//] [[[[:]module:]presenter:]action | this] [#fragment]
Il formato è supportato da tutti i tag Latte e da tutti i metodi del presentatore che funzionano con i collegamenti, cioè
n:href
, {link}
, {plink}
, link()
, lazyLink()
,
isLinkCurrent()
, redirect()
, redirectPermanent()
, forward()
,
canonicalize()
e anche LinkGenerator. Quindi, anche se negli esempi viene utilizzato
n:href
, potrebbe essere presente una qualsiasi delle funzioni.
La forma base è quindi Presenter:action
:
<a n:href="Home:default">home</a>
Se ci si collega all'azione del presentatore corrente, si può omettere il suo nome:
<a n:href="default">home</a>
Se l'azione è default
, possiamo ometterlo, ma i due punti devono rimanere:
<a n:href="Home:">home</a>
I collegamenti possono anche puntare ad altri moduli. In questo
caso, i collegamenti si distinguono in relativi ai sottomoduli o assoluti. Il principio è analogo a quello dei percorsi su
disco, solo che al posto degli slash ci sono i punti. Supponiamo che il presentatore attuale faccia parte del modulo
Front
, quindi scriveremo:
<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 caso particolare è il collegamento a se stesso. Qui scriveremo this
come target.
<a n:href="this">refresh</a>
Possiamo collegarci a una determinata parte della pagina HTML tramite un cosiddetto frammento dopo il simbolo hash
#
:
<a n:href="Home:#main">link to Home:default and fragment #main</a>
Percorsi assoluti
I link generati da 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, aggiungere due barre all'inizio (ad esempio, n:href="//Home:"
). Oppure si può
impostare il presentatore in modo che generi solo collegamenti assoluti, impostando
$this->absoluteUrls = true
.
Collegamento alla pagina corrente
Il target this
creerà un collegamento alla pagina corrente:
<a n:href="this">refresh</a>
Allo stesso tempo, tutti i parametri specificati nella firma dell'elemento action<Action>()
o
render<View>()
se il metodo action<Action>()
non è definito, vengono trasferiti. Quindi, se
ci troviamo nelle pagine Product:show
e id:123
, il collegamento a this
passerà anche
questo parametro.
Naturalmente, è possibile specificare direttamente i parametri:
<a n:href="this refresh: 1">refresh</a>
La funzione isLinkCurrent()
determina se la destinazione del link è la stessa della pagina corrente. Questo può
essere utilizzato, ad esempio, in un modello per differenziare i collegamenti, ecc.
I parametri sono gli stessi del metodo link()
, ma è anche possibile utilizzare il carattere jolly *
al posto di un'azione specifica, ovvero qualsiasi azione del presentatore.
{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>
Una forma abbreviata può essere usata in combinazione con n:href
in un singolo elemento:
<a n:class="isLinkCurrent() ? active" n:href="Product:detail">...</a>
Il carattere jolly *
sostituisce solo l'azione del presentatore, non il presentatore stesso.
Per sapere se ci troviamo in un certo modulo o in un suo sottomodulo, possiamo usare la funzione
isModuleCurrent(moduleName)
.
<li n:class="isModuleCurrent('MyEshop:Users') ? active">
<a n:href="Product:">...</a>
</li>
Collegamenti al segnale
Il target del collegamento può essere non solo il presentatore e l'azione, ma anche il segnale (chiamano il metodo
handle<Signal>()
). La sintassi è la seguente:
[//] [sub-component:]signal! [#fragment]
Il segnale è quindi contraddistinto dal punto esclamativo:
<a n:href="click!">signal</a>
È inoltre possibile creare un collegamento al segnale del sottocomponente (o del sottocomponente):
<a n:href="componentName:click!">signal</a>
Collegamenti nei componenti
Poiché i componenti sono unità riutilizzabili separate che non
dovrebbero avere relazioni con i presentatori circostanti, i collegamenti funzionano in modo leggermente diverso. L'attributo
Latte n:href
e il tag {link}
e i metodi dei componenti come link()
e altri considerano
sempre la destinazione come il nome del segnale. Pertanto non è necessario utilizzare un punto esclamativo:
<a n:href="click">signal, not an action</a>
Se vogliamo collegarci ai presentatori nel modello del componente, usiamo il tag {plink}
:
<a href={plink Home:default}>home</a>
o nel codice
$this->getPresenter()->link('Home:default')
Alias
A volte è utile assegnare un alias facilmente memorizzabile a una coppia Presentatore:azione. Per esempio, si può nominare
la pagina iniziale Front:Home:default
semplicemente come 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 collegamenti, vengono scritti utilizzando il simbolo at, ad esempio:
<a n:href="@admin">administration</a>
Sono supportati in tutti i metodi che lavorano con i collegamenti, come redirect()
e simili.
Collegamenti non validi
Può capitare di creare un collegamento non valido, sia perché fa riferimento a un presentatore inesistente, sia perché passa
più parametri di quelli che il metodo di destinazione riceve nella sua firma, sia quando non è possibile generare un URL per
l'azione mirata. Cosa fare con i collegamenti non validi è determinato dalla variabile statica
Presenter::$invalidLinkMode
. Essa può avere uno dei seguenti valori (costanti):
Presenter::InvalidLinkSilent
– modalità silenziosa, restituisce il simbolo#
come URLPresenter::InvalidLinkWarning
– verrà prodotto E_USER_WARNINGPresenter::InvalidLinkTextual
– avviso visivo, il testo dell'errore viene visualizzato nel linkPresenter::InvalidLinkException
– Viene lanciata l'eccezione InvalidLinkException.
L'impostazione predefinita in modalità di produzione è InvalidLinkWarning
e in modalità di sviluppo è
InvalidLinkWarning | InvalidLinkTextual
. InvalidLinkWarning
non uccide lo script nell'ambiente di
produzione, ma l'avviso viene registrato. Nell'ambiente di sviluppo, Tracy intercetta
l'avviso e visualizza la schermata di errore. Se InvalidLinkTextual
è impostato, il presentatore e i componenti
restituiscono il messaggio di errore come URL che inizia con #error:
. Per rendere visibili tali collegamenti,
possiamo aggiungere una regola CSS al nostro foglio di stile:
a[href^="#error:"] {
background: red;
color: white;
}
Se non vogliamo che vengano prodotti avvisi nell'ambiente di sviluppo, possiamo attivare la modalità silenziosa di collegamento non valido nella configurazione.
application:
silentLinks: true
Generatore di collegamenti
Come creare link con il metodo link()
, ma senza la presenza di un presentatore? Ecco perché Nette\Application\LinkGenerator.
LinkGenerator è un servizio che si può far passare attraverso il costruttore e poi creare link con il suo metodo
link()
.
C'è una differenza rispetto ai presentatori. LinkGenerator crea tutti i collegamenti come URL assoluti. Inoltre, non esiste
un “presentatore corrente”, quindi non è possibile specificare solo il nome dell'azione link('default')
o i percorsi relativi ai moduli.
I collegamenti non validi lanciano sempre Nette\Application\UI\InvalidLinkException
.