Nette Documentation Preview

syntax
Criando Links URL
*****************

<div class=perex>

Criar links no Nette é tão simples quanto apontar o dedo. Basta apontar e o framework faz todo o trabalho por você. Vamos mostrar:

- como criar links em templates e em outros lugares
- como distinguir um link para a página atual
- o que fazer com links inválidos

</div>


Graças ao [roteamento bidirecional |routing], você nunca precisará escrever URLs fixas da sua aplicação em templates ou código, que podem mudar posteriormente, ou montá-las de forma complicada. No link, basta indicar o presenter e a ação, passar quaisquer parâmetros e o framework gerará a URL por si só. Na verdade, é muito semelhante a chamar uma função. Você vai gostar disso.


No template do presenter
========================

Mais frequentemente, criamos links em templates e um ótimo auxiliar é o atributo `n:href`:

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

Observe que, em vez do atributo HTML `href`, usamos o [n:atributo |latte:syntax#n:atributos] `n:href`. Seu valor não é uma URL, como seria no caso do atributo `href`, but o nome do presenter e da ação.

Clicar no link é, simplificadamente, algo como chamar o método `ProductPresenter::renderShow()`. E se ele tiver parâmetros em sua assinatura, podemos chamá-lo com argumentos:

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

Também é possível passar parâmetros nomeados. O link a seguir passa o parâmetro `lang` com o valor `pt`:

```latte
<a n:href="Product:show $product->id, lang: pt">detalhe do produto</a>
```

Se o método `ProductPresenter::renderShow()` não tiver `$lang` em sua assinatura, ele pode obter o valor do parâmetro usando `$lang = $this->getParameter('lang')` ou da [propriedade |presenters#Parâmetros da requisição].

Se os parâmetros estiverem armazenados em um array, eles podem ser expandidos com o operador `...` (no Latte 2.x, com o operador `(expand)`):

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

Nos links, os chamados [parâmetros persistentes |presenters#Parâmetros persistentes] também são transmitidos automaticamente.

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

```latte
O endereço é: {link Home:default}
```


No código
=========

Para criar um link no presenter, usa-se o método `link()`:

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

Os parâmetros também podem ser passados através de um array, onde também podem ser especificados parâmetros nomeados:

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

Links também podem ser criados sem um presenter, para isso existe o [#LinkGenerator] e seu método `link()`.


Links para o presenter
======================

Se o destino do link for um presenter e uma ação, ele tem esta sintaxe:

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

O formato é suportado por todas as tags Latte e todos os métodos do presenter que trabalham 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, qualquer uma das funções poderia estar lá.

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

```latte
<a n:href="Home:default">página inicial</a>
```

Se estivermos vinculando a uma ação do presenter atual, podemos omitir seu nome:

```latte
<a n:href="default">página inicial</a>
```

Se o destino for a ação `default`, podemos omiti-la, mas os dois pontos devem permanecer:

```latte
<a n:href="Home:">página inicial</a>
```

Links também podem apontar para outros [módulos |directory-structure#Presenters e templates]. Aqui, os links são distinguidos entre relativos para um submódulo aninhado ou absolutos. O princípio é análogo aos caminhos no disco, apenas em vez de barras, são dois pontos. Suponha que o presenter atual faça parte do módulo `Front`, então escrevemos:

```latte
<a n:href="Shop:Product:show">link para Front:Shop:Product:show</a>
<a n:href=":Admin:Product:show">link para Admin:Product:show</a>
```

Um caso especial é um link [para si mesmo |#Link para a página atual], onde especificamos `this` como destino.

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

Podemos vincular a uma parte específica da página através do chamado fragmento após o caractere de cerquilha `#`:

```latte
<a n:href="Home:#main">link para Home:default e fragmento #main</a>
```


Caminhos absolutos
==================

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

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


Link para a página atual
========================

O destino `this` cria um link para a página atual:

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

Ao mesmo tempo, todos os parâmetros especificados na assinatura do método `action<Action>()` ou `render<View>()` são transmitidos, se `action<Action>()` não estiver definida. Portanto, se estivermos na página `Product:show` e `id: 123`, o link para `this` também passará este parâmetro.

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

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

A função `isLinkCurrent()` verifica se o destino do link é idêntico à página atual. Isso pode ser usado, por exemplo, em um template para diferenciar links, etc.

Os parâmetros são os mesmos do método `link()`, mas adicionalmente é possível usar o caractere curinga `*` em vez de uma ação específica, o que significa qualquer ação do presenter dado.

```latte
{if !isLinkCurrent('Admin:login')}
	<a n:href="Admin:login">Faça login</a>
{/if}

<li n:class="isLinkCurrent('Product:*') ? active">
	<a n:href="Product:">...</a>
</li>
```

Em combinação com `n:href` em um único elemento, uma forma abreviada pode ser usada:

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

O caractere curinga `*` só pode ser usado no lugar da ação, não do presenter.

Para verificar se estamos em um determinado módulo ou seu submódulo, usamos o método `isModuleCurrent(moduleName)`.

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


Links para sinal
================

O destino de um link não precisa ser apenas um presenter e uma ação, mas também um [sinal |components#Sinal] (eles chamam o método `handle<Signal>()`). Então a sintaxe é a seguinte:

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

O sinal é, portanto, distinguido por um ponto de exclamação:

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

Também é possível criar um link para o sinal de um subcomponente (ou sub-subcomponente):

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


Links no componente
===================

Como os [componentes|components] são unidades reutilizáveis separadas que não devem ter vínculos com os presenters circundantes, os links funcionam um pouco diferente aqui. O atributo Latte `n:href` e a tag `{link}`, bem como os métodos do componente como `link()` e outros, consideram o destino do link **sempre como o nome de um sinal**. Portanto, nem mesmo é necessário incluir o ponto de exclamação:

```latte
<a n:href="click">sinal, não ação</a>
```

Se quiséssemos vincular a presenters no template do componente, usaríamos a tag `{plink}`:

```latte
<a href={plink Home:default}>início</a>
```

ou no código

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


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

Às vezes, pode ser útil atribuir um alias fácil de lembrar a um par Presenter:action. Por exemplo, nomear a página inicial `Front:Home:default` simplesmente como `home` ou `Admin:Dashboard:default` como `admin`.

Aliases são definidos na [configuração|configuration] sob a chave `application › aliases`:

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

Nos links, eles são então escritos usando um arroba, por exemplo:

```latte
<a n:href="@admin">administração</a>
```

Eles também são suportados em todos os métodos que trabalham com links, como `redirect()` e similares.


Links inválidos
===============

Pode acontecer que criemos um link inválido - seja porque ele leva a um presenter inexistente, ou porque passa mais parâmetros do que o método de destino aceita em sua assinatura, ou quando uma URL não pode ser gerada para a ação de destino. Como lidar com links inválidos é determinado pela variável estática `Presenter::$invalidLinkMode`. Ela pode assumir uma combinação destes valores (constantes):

- `Presenter::InvalidLinkSilent` - modo silencioso, o caractere # é retornado como URL
- `Presenter::InvalidLinkWarning` - um aviso E_USER_WARNING é lançado, que será registrado no modo de produção, mas não causará a interrupção da execução do script
- `Presenter::InvalidLinkTextual` - aviso visual, exibe o erro diretamente no link
- `Presenter::InvalidLinkException` - a exceção InvalidLinkException é lançada

A configuração padrão é `InvalidLinkWarning` no modo de produção e `InvalidLinkWarning | InvalidLinkTextual` no modo de desenvolvimento. `InvalidLinkWarning` no ambiente de produção não causa a interrupção do script, mas o aviso será registrado. No ambiente de desenvolvimento, ele é capturado pelo [Tracy |tracy:] e exibe uma bluescreen. `InvalidLinkTextual` funciona retornando uma mensagem de erro como URL, que começa com os caracteres `#error:`. Para tornar esses links visíveis à primeira vista, adicionamos ao CSS:

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

Se não quisermos que avisos sejam produzidos no ambiente de desenvolvimento, podemos definir o modo silencioso diretamente na [configuração|configuration].

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


LinkGenerator
=============

Como criar links com conforto semelhante ao método `link()`, mas sem a presença de um presenter? Para isso existe a [api:Nette\Application\LinkGenerator].

LinkGenerator é um serviço que você pode solicitar via construtor e, em seguida, criar links usando seu método `link()`.

Há uma diferença em relação aos presenters. O LinkGenerator cria todos os links diretamente como URLs absolutas. Além disso, não existe um "presenter atual", então não é possível especificar apenas o nome da ação como destino `link('default')` ou usar caminhos relativos para módulos.

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

Criando Links URL

Criar links no Nette é tão simples quanto apontar o dedo. Basta apontar e o framework faz todo o trabalho por você. Vamos mostrar:

  • como criar links em templates e em outros lugares
  • como distinguir um link para a página atual
  • o que fazer com links inválidos

Graças ao roteamento bidirecional, você nunca precisará escrever URLs fixas da sua aplicação em templates ou código, que podem mudar posteriormente, ou montá-las de forma complicada. No link, basta indicar o presenter e a ação, passar quaisquer parâmetros e o framework gerará a URL por si só. Na verdade, é muito semelhante a chamar uma função. Você vai gostar disso.

No template do presenter

Mais frequentemente, criamos links em templates e um ótimo auxiliar é o atributo n:href:

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

Observe que, em vez do atributo HTML href, usamos o n:atributo n:href. Seu valor não é uma URL, como seria no caso do atributo href, but o nome do presenter e da ação.

Clicar no link é, simplificadamente, algo como chamar o 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">detalhe do produto</a>

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

<a n:href="Product:show $product->id, lang: pt">detalhe do produto</a>

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

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

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

Nos links, os chamados parâmetros persistentes também são transmitidos automaticamente.

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

O endereço é: {link Home:default}

No código

Para criar um link no presenter, usa-se o método link():

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

Os parâmetros também podem ser passados através de um array, onde também podem ser especificados parâmetros nomeados:

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

Links também podem ser criados sem um presenter, para isso existe o LinkGenerator e seu método link().

Se o destino do link for um presenter e uma ação, ele tem esta sintaxe:

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

O formato é suportado por todas as tags Latte e todos os métodos do presenter que trabalham 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, qualquer uma das funções poderia estar lá.

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

<a n:href="Home:default">página inicial</a>

Se estivermos vinculando a uma ação do presenter atual, podemos omitir seu nome:

<a n:href="default">página inicial</a>

Se o destino for a ação default, podemos omiti-la, mas os dois pontos devem permanecer:

<a n:href="Home:">página inicial</a>

Links também podem apontar para outros módulos. Aqui, os links são distinguidos entre relativos para um submódulo aninhado ou absolutos. O princípio é análogo aos caminhos no disco, apenas em vez de barras, são dois pontos. Suponha que o presenter atual faça parte do módulo Front, então escrevemos:

<a n:href="Shop:Product:show">link para Front:Shop:Product:show</a>
<a n:href=":Admin:Product:show">link para Admin:Product:show</a>

Um caso especial é um link para si mesmo, onde especificamos this como destino.

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

Podemos vincular a uma parte específica da página através do chamado fragmento após o caractere de cerquilha #:

<a n:href="Home:#main">link para Home:default e fragmento #main</a>

Caminhos absolutos

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

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

O destino this cria um link para a página atual:

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

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

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

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

A função isLinkCurrent() verifica se o destino do link é idêntico à página atual. Isso pode ser usado, por exemplo, em um template para diferenciar links, etc.

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

{if !isLinkCurrent('Admin:login')}
	<a n:href="Admin:login">Faça login</a>
{/if}

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

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

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

O caractere curinga * só pode ser usado no lugar da ação, não do presenter.

Para verificar se estamos em um determinado módulo ou seu submódulo, usamos o método isModuleCurrent(moduleName).

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

O destino de um link não precisa ser apenas um presenter e uma ação, mas também um sinal (eles chamam o método handle<Signal>()). Então a sintaxe é a seguinte:

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

O sinal é, portanto, distinguido por um ponto de exclamação:

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

Também é possível criar um link para o sinal de um subcomponente (ou sub-subcomponente):

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

Como os componentes são unidades reutilizáveis separadas que não devem ter vínculos com os presenters circundantes, os links funcionam um pouco diferente aqui. O atributo Latte n:href e a tag {link}, bem como os métodos do componente como link() e outros, consideram o destino do link sempre como o nome de um sinal. Portanto, nem mesmo é necessário incluir o ponto de exclamação:

<a n:href="click">sinal, não ação</a>

Se quiséssemos vincular a presenters no template do componente, usaríamos a tag {plink}:

<a href={plink Home:default}>início</a>

ou no código

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

Aliases

Às vezes, pode ser útil atribuir um alias fácil de lembrar a um par Presenter:action. Por exemplo, nomear a página inicial Front:Home:default simplesmente como home ou Admin:Dashboard:default como admin.

Aliases são definidos na configuração sob a chave application › aliases:

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

Nos links, eles são então escritos usando um arroba, por exemplo:

<a n:href="@admin">administração</a>

Eles também são suportados em todos os métodos que trabalham com links, como redirect() e similares.

Pode acontecer que criemos um link inválido – seja porque ele leva a um presenter inexistente, ou porque passa mais parâmetros do que o método de destino aceita em sua assinatura, ou quando uma URL não pode ser gerada para a ação de destino. Como lidar com links inválidos é determinado pela variável estática Presenter::$invalidLinkMode. Ela pode assumir uma combinação destes valores (constantes):

  • Presenter::InvalidLinkSilent – modo silencioso, o caractere # é retornado como URL
  • Presenter::InvalidLinkWarning – um aviso E_USER_WARNING é lançado, que será registrado no modo de produção, mas não causará a interrupção da execução do script
  • Presenter::InvalidLinkTextual – aviso visual, exibe o erro diretamente no link
  • Presenter::InvalidLinkException – a exceção InvalidLinkException é lançada

A configuração padrão é InvalidLinkWarning no modo de produção e InvalidLinkWarning | InvalidLinkTextual no modo de desenvolvimento. InvalidLinkWarning no ambiente de produção não causa a interrupção do script, mas o aviso será registrado. No ambiente de desenvolvimento, ele é capturado pelo Tracy e exibe uma bluescreen. InvalidLinkTextual funciona retornando uma mensagem de erro como URL, que começa com os caracteres #error:. Para tornar esses links visíveis à primeira vista, adicionamos ao CSS:

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

Se não quisermos que avisos sejam produzidos no ambiente de desenvolvimento, podemos definir o modo silencioso diretamente na configuração.

application:
	silentLinks: true

LinkGenerator

Como criar links com conforto semelhante ao método link(), mas sem a presença de um presenter? Para isso existe a Nette\Application\LinkGenerator.

LinkGenerator é um serviço que você pode solicitar via construtor e, em seguida, criar links usando seu método link().

Há uma diferença em relação aos presenters. O LinkGenerator cria todos os links diretamente como URLs absolutas. Além disso, não existe um „presenter atual“, então não é possível especificar apenas o nome da ação como destino link('default') ou usar caminhos relativos para módulos.

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