Nette Documentation Preview

syntax
Creazione di link URL
*********************

<div class=perex>

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

</div>


Grazie al [routing bidirezionale |routing], 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`:

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

Nota che invece dell'attributo HTML `href`, abbiamo usato l'[attributo n |latte:syntax#n:attributi] `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:

```latte
<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`:

```latte
<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à |presenters#Parametri della richiesta].

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

```latte
{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 |presenters#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}`:

```latte
L'indirizzo è: {link Home:default}
```


Nel codice
==========

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

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

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

```php
$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`:

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

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

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

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

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

I link possono anche puntare ad altri [moduli |directory-structure#Presenter e template]. 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:

```latte
<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 |#Link alla pagina corrente], dove specifichiamo `this` come destinazione.

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

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

```latte
<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:

```latte
<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:

```latte
<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.

```latte
{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:

```latte
<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)`.

```latte
<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 |components#Segnale] (chiamano il metodo `handle<Signal>()`). Allora la sintassi è la seguente:

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

Il segnale è quindi distinto dal punto esclamativo:

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

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

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


Link nel componente
===================

Poiché i [componenti |components] 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:

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

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

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

o nel codice

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


Alias .{data-version:v3.2.2}
============================

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|configuration] sotto la chiave `application › aliases`:

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

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

```latte
<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 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 |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:

```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|configuration].

```neon
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'è [api: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`.

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.