Nette Documentation Preview

syntax
Creación de enlaces URL
***********************

<div class=perex>

Crear enlaces en Nette es tan fácil como señalar con el dedo. Sólo tienes que señalar y el framework hará todo el trabajo por ti. Se lo mostraremos:

- cómo crear enlaces en plantillas y en otros lugares
- cómo distinguir un enlace de la página actual
- qué pasa con los enlaces no válidos

</div>


Gracias al [enrutamiento bidireccional |routing], nunca tendrás que codificar las URL de la aplicación en las plantillas o el código, que pueden cambiar más tarde o ser complicadas de componer. Basta con especificar el presentador y la acción en el enlace, pasar cualquier parámetro y el framework generará la URL por sí mismo. De hecho, es muy similar a llamar a una función. Te gustará.


En la plantilla de presentador .[#toc-in-the-presenter-template]
================================================================

La mayoría de las veces creamos enlaces en las plantillas y una gran ayuda es el atributo `n:href`:

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

Tenga en cuenta que en lugar del atributo HTML `href` hemos utilizado [n:attribute |latte:syntax#n:attributes] `n:href`. Su valor no es una URL, como estás acostumbrado con el atributo `href`, sino el nombre del presentador y la acción.

Hacer clic en un enlace es, en pocas palabras, algo así como llamar a un método `ProductPresenter::renderShow()`. Y si tiene parámetros en su firma, podemos llamarlo con argumentos:

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

También es posible pasar parámetros con nombre. El siguiente enlace pasa el parámetro `lang` con el valor `en`:

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

Si el método `ProductPresenter::renderShow()` no tiene `$lang` en su firma, puede leer el valor del parámetro usando `$lang = $this->getParameter('lang')`.

Si los parámetros se almacenan en una matriz, pueden expandirse con el operador `...` (o `(expand)` en Latte 2.x):

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

Los llamados [parámetros persistentes |presenters#persistent parameters] también se pasan automáticamente en los enlaces.

El atributo `n:href` es muy útil para las etiquetas HTML `<a>`. Si queremos imprimir el enlace en otro lugar, por ejemplo en el texto, utilizamos `{link}`:

```latte
URL is: {link Home:default}
```


En el código .[#toc-in-the-code]
================================

El método `link()` se utiliza para crear un enlace en el presentador:

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

Los parámetros también se pueden pasar como una matriz en la que también se pueden especificar parámetros con nombre:

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

También se pueden crear enlaces sin presentador, utilizando el [LinkGenerator |#LinkGenerator] y su método `link()`.


Enlaces con presentador .[#toc-links-to-presenter]
==================================================

Si el objetivo del enlace es presentador y acción, tiene esta sintaxis:

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

El formato es soportado por todas las etiquetas Latte y todos los métodos de presentador que trabajan con enlaces, es decir `n:href`, `{link}`, `{plink}`, `link()`, `lazyLink()`, `isLinkCurrent()`, `redirect()`, `redirectPermanent()`, `forward()`, `canonicalize()` y también [LinkGenerator |#LinkGenerator]. Así que aunque en los ejemplos se utilice `n:href`, podría ser cualquiera de las funciones.

Por lo tanto, la forma básica es `Presenter:action`:

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

Si enlazamos con la acción del presentador actual, podemos omitir su nombre:

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

Si la acción es `default`, podemos omitirlo, pero los dos puntos deben permanecer:

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

Los enlaces también pueden apuntar a otros [módulos |modules]. Aquí, los enlaces se distinguen en relativos a los submódulos, o absolutos. El principio es análogo a las rutas de disco, sólo que en lugar de barras inclinadas hay dos puntos. Supongamos que el presentador real forma parte del módulo `Front`, entonces escribiremos:

```latte
<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 especial es el [enlace a sí mismo |#Links to Current Page]. Aquí escribiremos `this` como objetivo.

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

Podemos enlazar a una parte determinada de la página HTML mediante un fragmento llamado `#` después del símbolo de almohadilla `#`:

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


Rutas absolutas .[#toc-absolute-paths]
======================================

Los enlaces generados por `link()` o `n:href` son siempre rutas absolutas (es decir, empiezan por `/`), pero no URLs absolutas con protocolo y dominio como `https://domain`.

Para generar una URL absoluta, añada dos barras al principio (por ejemplo, `n:href="//Home:"`). También puede hacer que el presentador genere sólo enlaces absolutos configurando `$this->absoluteUrls = true`.


Enlace a la página actual .[#toc-link-to-current-page]
======================================================

El destino `this` creará un enlace a la página actual:

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

Al mismo tiempo, todos los parámetros especificados en la firma de la directiva `render<View>()` o `action<Action>()` se transfieren. Así, si estamos en las páginas `Product:show` y `id:123`, el enlace a `this` también pasará este parámetro.

Por supuesto, es posible especificar los parámetros directamente:

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

La función `isLinkCurrent()` determina si el destino del enlace es el mismo que la página actual. Esto puede utilizarse, por ejemplo, en una plantilla para diferenciar enlaces, etc.

Los parámetros son los mismos que para el método `link()`, pero también es posible utilizar el comodín `*` en lugar de una acción específica, lo que significa cualquier acción del presentador.

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

Se puede utilizar una forma abreviada en combinación con `n:href` en un solo elemento:

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

El carácter comodín `*` sólo sustituye a la acción del presentador, no al presentador en sí.

Para saber si estamos en un módulo determinado o en su submódulo podemos utilizar la función `isModuleCurrent(moduleName)`.

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


Enlaces a la señal .[#toc-links-to-signal]
==========================================

El objetivo del enlace no sólo puede ser el presentador y la acción, sino también la [señal |components#Signal] (llaman al método `handle<Signal>()`). La sintaxis es la siguiente:

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

Por lo tanto, la señal se distingue por el signo de exclamación:

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

También puede crear un enlace a la señal del subcomponente (o sub-subcomponente):

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


Enlaces en el componente .[#toc-links-in-component]
===================================================

Dado que los [componentes |components] son unidades reutilizables independientes que no deben tener ninguna relación con los presentadores circundantes, los enlaces funcionan de forma un poco diferente. El atributo Latte `n:href` y la etiqueta `{link}` y los métodos de componentes como `link()` y otros siempre consideran el objetivo **como el nombre de la señal**. Por lo tanto, no es necesario utilizar un signo de exclamación:

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

Si queremos enlazar con presentadores en la plantilla de componentes, utilizaremos la etiqueta `{plink}`:

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

o en el código

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


Enlaces no válidos .[#toc-invalid-links]
========================================

Puede ocurrir que creemos un enlace no válido, bien porque haga referencia a un presentador inexistente, bien porque pase más parámetros de los que el método de destino recibe en su firma, o bien cuando no puede haber una URL generada para la acción de destino. Lo que hay que hacer con los enlaces no válidos viene determinado por la variable estática `Presenter::$invalidLinkMode`. Puede tener uno de estos valores (constantes):

- `Presenter::InvalidLinkSilent` - modo silencioso, devuelve el símbolo `#` como URL
- `Presenter::InvalidLinkWarning` - se producirá E_USER_WARNING
- `Presenter::InvalidLinkTextual` - advertencia visual, el texto del error se muestra en el enlace
- `Presenter::InvalidLinkException` - se lanzará una InvalidLinkException

La configuración por defecto en modo producción es `InvalidLinkWarning` y en modo desarrollo es `InvalidLinkWarning | InvalidLinkTextual`. `InvalidLinkWarning` no mata el script en el entorno de producción, pero la advertencia será registrada. En el entorno de desarrollo, [Tracy |tracy:] interceptará la advertencia y mostrará la pantalla azul de error. Si el `InvalidLinkTextual` está configurado, el presentador y los componentes devuelven el mensaje de error como URL que comienza con `#error:`. Para hacer visibles estos enlaces, podemos añadir una regla CSS a nuestra hoja de estilos:

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

Si no queremos que se produzcan advertencias en el entorno de desarrollo podemos activar el modo de enlace inválido silencioso en la [configuración |configuration].

```neon
application:
	silentLinks: true
```


Generador de enlaces .[#toc-linkgenerator]
==========================================

¿Cómo crear enlaces con el método `link()` comodidad, pero sin la presencia de un presentador? Es por eso que aquí está [api:Nette\Application\LinkGenerator].

LinkGenerator es un servicio que puede haber pasado por el constructor y luego crear enlaces utilizando su método `link()`.

Hay una diferencia en comparación con los presentadores. LinkGenerator crea todos los enlaces como URLs absolutas. Además, no existe un "presentador actual", por lo que no es posible especificar únicamente el nombre de la acción `link('default')` o las rutas relativas a los [módulos |modules].

Los enlaces no válidos siempre lanzan `Nette\Application\UI\InvalidLinkException`.

Creación de enlaces URL

Crear enlaces en Nette es tan fácil como señalar con el dedo. Sólo tienes que señalar y el framework hará todo el trabajo por ti. Se lo mostraremos:

  • cómo crear enlaces en plantillas y en otros lugares
  • cómo distinguir un enlace de la página actual
  • qué pasa con los enlaces no válidos

Gracias al enrutamiento bidireccional, nunca tendrás que codificar las URL de la aplicación en las plantillas o el código, que pueden cambiar más tarde o ser complicadas de componer. Basta con especificar el presentador y la acción en el enlace, pasar cualquier parámetro y el framework generará la URL por sí mismo. De hecho, es muy similar a llamar a una función. Te gustará.

En la plantilla de presentador

La mayoría de las veces creamos enlaces en las plantillas y una gran ayuda es el atributo n:href:

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

Tenga en cuenta que en lugar del atributo HTML href hemos utilizado n:attribute n:href. Su valor no es una URL, como estás acostumbrado con el atributo href, sino el nombre del presentador y la acción.

Hacer clic en un enlace es, en pocas palabras, algo así como llamar a un método ProductPresenter::renderShow(). Y si tiene parámetros en su firma, podemos llamarlo con argumentos:

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

También es posible pasar parámetros con nombre. El siguiente enlace pasa el parámetro lang con el valor en:

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

Si el método ProductPresenter::renderShow() no tiene $lang en su firma, puede leer el valor del parámetro usando $lang = $this->getParameter('lang').

Si los parámetros se almacenan en una matriz, pueden expandirse con el operador ... (o (expand) en Latte 2.x):

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

Los llamados parámetros persistentes también se pasan automáticamente en los enlaces.

El atributo n:href es muy útil para las etiquetas HTML <a>. Si queremos imprimir el enlace en otro lugar, por ejemplo en el texto, utilizamos {link}:

URL is: {link Home:default}

En el código

El método link() se utiliza para crear un enlace en el presentador:

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

Los parámetros también se pueden pasar como una matriz en la que también se pueden especificar parámetros con nombre:

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

También se pueden crear enlaces sin presentador, utilizando el LinkGenerator y su método link().

Si el objetivo del enlace es presentador y acción, tiene esta sintaxis:

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

El formato es soportado por todas las etiquetas Latte y todos los métodos de presentador que trabajan con enlaces, es decir n:href, {link}, {plink}, link(), lazyLink(), isLinkCurrent(), redirect(), redirectPermanent(), forward(), canonicalize() y también LinkGenerator. Así que aunque en los ejemplos se utilice n:href, podría ser cualquiera de las funciones.

Por lo tanto, la forma básica es Presenter:action:

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

Si enlazamos con la acción del presentador actual, podemos omitir su nombre:

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

Si la acción es default, podemos omitirlo, pero los dos puntos deben permanecer:

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

Los enlaces también pueden apuntar a otros módulos. Aquí, los enlaces se distinguen en relativos a los submódulos, o absolutos. El principio es análogo a las rutas de disco, sólo que en lugar de barras inclinadas hay dos puntos. Supongamos que el presentador real forma parte del módulo Front, entonces escribiremos:

<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 especial es el enlace a sí mismo. Aquí escribiremos this como objetivo.

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

Podemos enlazar a una parte determinada de la página HTML mediante un fragmento llamado # después del símbolo de almohadilla #:

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

Rutas absolutas

Los enlaces generados por link() o n:href son siempre rutas absolutas (es decir, empiezan por /), pero no URLs absolutas con protocolo y dominio como https://domain.

Para generar una URL absoluta, añada dos barras al principio (por ejemplo, n:href="//Home:"). También puede hacer que el presentador genere sólo enlaces absolutos configurando $this->absoluteUrls = true.

El destino this creará un enlace a la página actual:

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

Al mismo tiempo, todos los parámetros especificados en la firma de la directiva render<View>() o action<Action>() se transfieren. Así, si estamos en las páginas Product:show y id:123, el enlace a this también pasará este parámetro.

Por supuesto, es posible especificar los parámetros directamente:

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

La función isLinkCurrent() determina si el destino del enlace es el mismo que la página actual. Esto puede utilizarse, por ejemplo, en una plantilla para diferenciar enlaces, etc.

Los parámetros son los mismos que para el método link(), pero también es posible utilizar el comodín * en lugar de una acción específica, lo que significa cualquier acción del presentador.

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

Se puede utilizar una forma abreviada en combinación con n:href en un solo elemento:

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

El carácter comodín * sólo sustituye a la acción del presentador, no al presentador en sí.

Para saber si estamos en un módulo determinado o en su submódulo podemos utilizar la función isModuleCurrent(moduleName).

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

El objetivo del enlace no sólo puede ser el presentador y la acción, sino también la señal (llaman al método handle<Signal>()). La sintaxis es la siguiente:

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

Por lo tanto, la señal se distingue por el signo de exclamación:

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

También puede crear un enlace a la señal del subcomponente (o sub-subcomponente):

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

Dado que los componentes son unidades reutilizables independientes que no deben tener ninguna relación con los presentadores circundantes, los enlaces funcionan de forma un poco diferente. El atributo Latte n:href y la etiqueta {link} y los métodos de componentes como link() y otros siempre consideran el objetivo como el nombre de la señal. Por lo tanto, no es necesario utilizar un signo de exclamación:

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

Si queremos enlazar con presentadores en la plantilla de componentes, utilizaremos la etiqueta {plink}:

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

o en el código

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

Puede ocurrir que creemos un enlace no válido, bien porque haga referencia a un presentador inexistente, bien porque pase más parámetros de los que el método de destino recibe en su firma, o bien cuando no puede haber una URL generada para la acción de destino. Lo que hay que hacer con los enlaces no válidos viene determinado por la variable estática Presenter::$invalidLinkMode. Puede tener uno de estos valores (constantes):

  • Presenter::InvalidLinkSilent – modo silencioso, devuelve el símbolo # como URL
  • Presenter::InvalidLinkWarning – se producirá E_USER_WARNING
  • Presenter::InvalidLinkTextual – advertencia visual, el texto del error se muestra en el enlace
  • Presenter::InvalidLinkException – se lanzará una InvalidLinkException

La configuración por defecto en modo producción es InvalidLinkWarning y en modo desarrollo es InvalidLinkWarning | InvalidLinkTextual. InvalidLinkWarning no mata el script en el entorno de producción, pero la advertencia será registrada. En el entorno de desarrollo, Tracy interceptará la advertencia y mostrará la pantalla azul de error. Si el InvalidLinkTextual está configurado, el presentador y los componentes devuelven el mensaje de error como URL que comienza con #error:. Para hacer visibles estos enlaces, podemos añadir una regla CSS a nuestra hoja de estilos:

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

Si no queremos que se produzcan advertencias en el entorno de desarrollo podemos activar el modo de enlace inválido silencioso en la configuración.

application:
	silentLinks: true

Generador de enlaces

¿Cómo crear enlaces con el método link() comodidad, pero sin la presencia de un presentador? Es por eso que aquí está Nette\Application\LinkGenerator.

LinkGenerator es un servicio que puede haber pasado por el constructor y luego crear enlaces utilizando su método link().

Hay una diferencia en comparación con los presentadores. LinkGenerator crea todos los enlaces como URLs absolutas. Además, no existe un „presentador actual“, por lo que no es posible especificar únicamente el nombre de la acción link('default') o las rutas relativas a los módulos.

Los enlaces no válidos siempre lanzan Nette\Application\UI\InvalidLinkException.