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()
.
Link al presenter
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
.
Link alla pagina corrente
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>
Link a segnali
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>
Link nel componente
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.
Link non validi
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 scriptPresenter::InvalidLinkTextual
– avviso visivo, stampa l'errore direttamente nel linkPresenter::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
.