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 recuperar el valor del
parámetro utilizando $lang = $this->getParameter('lang')
o desde la propiedad.
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()
.
Enlaces con presentador
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
.
Enlace a la página actual
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 action<Action>()
o
render<View>()
si el método action<Action>()
no está definido, 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>
Enlaces a la señal
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>
Enlaces en el componente
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')
Alias
A veces resulta útil asignar un alias fácil de recordar a un par Presentador:acción. Por ejemplo, puede nombrar la página
de inicio Front:Home:default
simplemente como home
o Admin:Dashboard:default
como
admin
.
Los alias se definen en la configuración con la clave
application › aliases
:
application:
aliases:
home: Front:Home:default
admin: Admin:Dashboard:default
sign: Front:Sign:in
En los enlaces, se escriben utilizando el símbolo arroba, por ejemplo:
<a n:href="@admin">administration</a>
Se admiten en todos los métodos que trabajan con enlaces, como redirect()
y similares.
Enlaces no válidos
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 URLPresenter::InvalidLinkWarning
– se producirá E_USER_WARNINGPresenter::InvalidLinkTextual
– advertencia visual, el texto del error se muestra en el enlacePresenter::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
.