Criação de links URL

Criar links em Nette é tão fácil quanto apontar um dedo. Basta apontar e a estrutura fará todo o trabalho por você. Nós mostraremos:

  • como criar links em modelos e em outros lugares
  • como distinguir um link para a página atual
  • E os links inválidos?

Graças ao roteamento bidirecional, você nunca terá que codificar as URLs dos aplicativos nos modelos ou códigos, que podem mudar mais tarde ou ser complicados para compor. Basta especificar o apresentador e a ação no link, passar quaisquer parâmetros e a estrutura gerará a própria URL. Na verdade, é muito semelhante a chamar uma função. Você vai gostar.

No modelo do apresentador

Na maioria das vezes criamos links em modelos e um grande ajudante é o atributo n:href:

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

Note que, em vez do atributo HTML href, usamos o atributo n: n:href. Seu valor não é uma URL, como você está acostumado com o atributo href, mas o nome do apresentador e da ação.

Clicando em um link é, simplesmente dito, algo como chamar um método ProductPresenter::renderShow(). E se ele tiver parâmetros em sua assinatura, podemos chamá-lo com argumentos:

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

Também é possível passar parâmetros nomeados. O seguinte link passa o parâmetro lang com o valor en:

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

Se o método ProductPresenter::renderShow() não tiver $lang em sua assinatura, ele poderá recuperar o valor do parâmetro usando $lang = $this->getParameter('lang') ou a partir da propriedade.

Se os parâmetros estiverem armazenados em uma matriz, eles podem ser expandidos com o operador ... (ou (expand) operador em Latte 2.x):

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

Os chamados parâmetros persistentes também são automaticamente passados nos links.

Atributo n:href é muito útil para tags HTML <a>. Se quisermos imprimir o link em outro lugar, por exemplo, no texto, usamos {link}:

URL is: {link Home:default}

No Código

O método link() é usado para criar um link no apresentador:

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

Os parâmetros também podem ser passados como uma matriz onde parâmetros nomeados também podem ser especificados:

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

Links também podem ser criados sem apresentador, usando o LinkGenerator e seu método link().

Se o alvo do link é o apresentador e a ação, ele tem esta sintaxe:

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

O formato é suportado por todas as etiquetas Latte e todos os métodos de apresentação que funcionam com links, ou seja n:href, {link}, {plink}, link(), lazyLink(), isLinkCurrent(), redirect(), redirectPermanent(), forward(), canonicalize() e também LinkGenerator. Portanto, mesmo que n:href seja usado nos exemplos, pode haver qualquer uma das funções.

A forma básica é, portanto, Presenter:action:

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

Se nos ligarmos à ação do atual apresentador, podemos omitir seu nome:

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

Se a ação é default, podemos omiti-la, mas o cólon deve permanecer:

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

Os links também podem apontar para outros módulos. Aqui, os links são diferenciados em relativos aos submódulos, ou absolutos. O princípio é análogo aos caminhos do disco, somente em vez de cortes existem colons. Vamos supor que o apresentador real faça parte do módulo Front, então escreveremos:

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

Um caso especial está ligado a si mesmo. Aqui escreveremos this como o alvo.

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

Podemos criar um link para uma determinada parte da página HTML através do chamado fragmento após o símbolo # hash:

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

Caminhos Absolutos

Links gerados por link() ou n:href são sempre caminhos absolutos (ou seja, começam com /), mas não URLs absolutas com um protocolo e domínio como https://domain.

Para gerar uma URL absoluta, acrescente duas barras ao início (por exemplo, n:href="//Home:"). Ou você pode mudar o apresentador para gerar apenas links absolutos, definindo $this->absoluteUrls = true.

A meta this irá criar um link para a página atual:

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

Ao mesmo tempo, todos os parâmetros especificados na assinatura do parâmetro action<Action>() ou render<View>() se o método action<Action>() não estiver definido, serão transferidos. Portanto, se estivermos nas páginas Product:show e id:123, o link para this também passará esse parâmetro.

Naturalmente, é possível especificar os parâmetros diretamente:

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

A função isLinkCurrent() determina se o alvo do link é o mesmo que a página atual. Isto pode ser usado, por exemplo, em um modelo para diferenciar links, etc.

Os parâmetros são os mesmos do método link(), mas também é possível utilizar o curinga * em vez de uma ação específica, o que significa qualquer ação do apresentador.

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

Uma forma abreviada pode ser usada em combinação com n:href em um único elemento:

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

O caráter curinga `*' substitui apenas a ação do apresentador, não o próprio apresentador.

Para saber se estamos em um determinado módulo ou em seu submódulo, podemos usar a função isModuleCurrent(moduleName).

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

O alvo do link pode não só ser o apresentador e a ação, mas também o sinal (eles chamam o método handle<Signal>()). A sintaxe é a seguinte:

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

O sinal distingue-se, portanto, pelo ponto de exclamação:

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

Você também pode criar um link para o sinal do subcomponente (ou sub-subcomponente):

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

Como os componentes são unidades reutilizáveis separadas que não devem ter nenhuma relação com os apresentadores ao redor, os elos funcionam de forma um pouco diferente. O atributo Latte n:href e tag {link} e os métodos de componentes como link() e outros sempre consideram o alvo ** como o nome do sinal***. Portanto, não é necessário o uso de um ponto de exclamação:

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

Se quisermos fazer um link para apresentadores no modelo de componente, usamos a tag {plink}:

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

ou no código

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

Pode acontecer de criarmos um link inválido – seja porque ele se refere a um apresentador inexistente, ou porque ele passa mais parâmetros que o método alvo recebe em sua assinatura, ou quando não pode haver uma URL gerada para a ação alvo. O que fazer com links inválidos é determinado pela variável estática Presenter::$invalidLinkMode. Ela pode ter um destes valores (constantes):

  • Presenter::InvalidLinkSilent – modo silencioso, retorna o símbolo # como URL
  • Presenter::InvalidLinkWarning – E_USER_WARNING será produzido
  • Presenter::InvalidLinkTextual – aviso visual, o texto de erro é exibido no link
  • Presenter::InvalidLinkException – InvalidLinkException será lançada

A configuração padrão no modo de produção é InvalidLinkWarning e no modo de desenvolvimento é InvalidLinkWarning | InvalidLinkTextual. InvalidLinkWarning não mata o script no ambiente de produção, mas o aviso será registrado. No ambiente de desenvolvimento, Tracy interceptará o aviso e exibirá a tela de erro bluescreen. Se o InvalidLinkTextual estiver configurado, o apresentador e os componentes retornarão a mensagem de erro como URL, que é estrelada com #error:. Para tornar tais links visíveis, podemos adicionar uma regra CSS à nossa folha de estilo:

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

Se não quisermos que os avisos sejam produzidos no ambiente de desenvolvimento, podemos ativar o modo de link inválido silencioso na configuração.

application:
	silentLinks: true

LinkGenerator

Como criar vínculos com o método link() conforto, mas sem a presença de um apresentador? É por isso que aqui está Nette\Application\LinkGenerator.

O LinkGenerator é um serviço que você pode ter passado pelo construtor e depois criar links usando seu método link().

Há uma diferença em comparação com os apresentadores. O LinkGenerator cria todos os links como URLs absolutos. Além disso, não há “apresentador atual”, portanto não é possível especificar apenas o nome da ação link('default') ou os caminhos relativos aos módulos.

Links inválidos sempre lançam Nette\Application\UI\InvalidLinkException.

versão: 4.0