Création de liens URL

Créer des liens dans Nette est aussi simple que de pointer du doigt. Il suffit de viser et le framework fait tout le travail pour vous. Nous allons montrer :

  • comment créer des liens dans les templates et ailleurs
  • comment distinguer un lien vers la page actuelle
  • que faire des liens invalides

Grâce au routage bidirectionnel, vous n'aurez jamais à écrire en dur les URL de votre application dans les templates ou le code, URL qui pourraient changer plus tard, ou à les composer de manière compliquée. Dans le lien, il suffit d'indiquer le presenter et l'action, de passer d'éventuels paramètres, et le framework générera l'URL lui-même. En fait, c'est très similaire à l'appel d'une fonction. Vous allez adorer ça.

Dans le template du presenter

Le plus souvent, nous créons des liens dans les templates et l'attribut n:href est un excellent assistant :

<a n:href="Product:show">détail</a>

Notez qu'au lieu de l'attribut HTML href, nous avons utilisé un n:attribut n:href. Sa valeur n'est alors pas une URL, comme ce serait le cas avec l'attribut href, mais le nom du presenter et de l'action.

Cliquer sur le lien est, pour simplifier, quelque chose comme appeler la méthode ProductPresenter::renderShow(). Et si elle a des paramètres dans sa signature, nous pouvons l'appeler avec des arguments :

<a n:href="Product:show $product->id, $product->slug">détail du produit</a>

Il est également possible de passer des paramètres nommés. Le lien suivant passe le paramètre lang avec la valeur cs :

<a n:href="Product:show $product->id, lang: cs">détail du produit</a>

Si la méthode ProductPresenter::renderShow() n'a pas $lang dans sa signature, elle peut récupérer la valeur du paramètre en utilisant $lang = $this->getParameter('lang') ou depuis une propriété.

Si les paramètres sont stockés dans un tableau, ils peuvent être développés avec l'opérateur ... (dans Latte 2.x, l'opérateur (expand)) :

{var $args = [$product->id, lang => cs]}
<a n:href="Product:show ...$args">détail du produit</a>

Les liens transmettent également automatiquement les paramètres persistants.

L'attribut n:href est très pratique pour les balises HTML <a>. Si nous voulons afficher le lien ailleurs, par exemple dans du texte, nous utilisons {link} :

L'adresse est : {link Home:default}

Dans le code

Pour créer un lien dans le presenter, la méthode link() est utilisée :

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

Les paramètres peuvent également être passés via un tableau, où des paramètres nommés peuvent également être spécifiés :

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

Les liens peuvent également être créés sans presenter, c'est à cela que sert LinkGenerator et sa méthode link().

Liens vers un presenter

Si la cible du lien est un presenter et une action, la syntaxe est la suivante :

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

Ce format est pris en charge par toutes les balises Latte et toutes les méthodes du presenter qui fonctionnent avec des liens, c'est-à-dire n:href, {link}, {plink}, link(), lazyLink(), isLinkCurrent(), redirect(), redirectPermanent(), forward(), canonicalize() et aussi LinkGenerator. Ainsi, même si n:href est utilisé dans les exemples, n'importe laquelle de ces fonctions pourrait être là.

La forme de base est donc Presenter:action :

<a n:href="Home:default">page d'accueil</a>

Si nous lions vers une action du presenter actuel, nous pouvons omettre son nom :

<a n:href="default">page d'accueil</a>

Si la cible est l'action default, nous pouvons l'omettre, mais les deux-points doivent rester :

<a n:href="Home:">page d'accueil</a>

Les liens peuvent également pointer vers d'autres modules. Ici, les liens sont distingués comme relatifs à un sous-module imbriqué, ou absolus. Le principe est analogue aux chemins sur disque, sauf que les deux-points remplacent les barres obliques. Supposons que le presenter actuel fasse partie du module Front, alors nous écririons :

<a n:href="Shop:Product:show">lien vers Front:Shop:Product:show</a>
<a n:href=":Admin:Product:show">lien vers Admin:Product:show</a>

Un cas spécial est un lien vers soi-même, où nous spécifions this comme cible.

<a n:href="this">rafraîchir</a>

Nous pouvons lier vers une partie spécifique de la page via un fragment après le signe dièse # :

<a n:href="Home:#main">lien vers Home:default et le fragment #main</a>

Chemins absolus

Les liens générés à l'aide de link() ou n:href sont toujours des chemins absolus (c'est-à-dire qu'ils commencent par /), mais pas des URL absolues avec protocole et domaine comme https://domain.

Pour générer une URL absolue, ajoutez deux barres obliques au début (par ex. n:href="//Home:"). Ou vous pouvez configurer le presenter pour ne générer que des liens absolus en définissant $this->absoluteUrls = true.

Lien vers la page actuelle

La cible this crée un lien vers la page actuelle :

<a n:href="this">rafraîchir</a>

En même temps, tous les paramètres spécifiés dans la signature de la méthode action<Action>() ou render<View>() sont également transmis, si action<Action>() n'est pas définie. Donc, si nous sommes sur la page Product:show avec id: 123, le lien vers this transmettra également ce paramètre.

Bien sûr, il est possible de spécifier les paramètres directement :

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

La fonction isLinkCurrent() vérifie si la cible du lien est identique à la page actuelle. Cela peut être utilisé, par exemple, dans un template pour distinguer les liens, etc.

Les paramètres sont les mêmes que pour la méthode link(), mais il est en plus possible de spécifier un caractère générique * à la place d'une action spécifiques, ce qui signifie n'importe quelle action du presenter donné.

{if !isLinkCurrent('Admin:login')}
	<a n:href="Admin:login">Connectez-vous</a>
{/if}

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

En combinaison avec n:href dans un seul élément, une forme abrégée peut être utilisée :

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

Le caractère générique * ne peut être utilisé qu'à la place de l'action, pas du presenter.

Pour vérifier si nous sommes dans un certain module ou son sous-module, utilisez la méthode isModuleCurrent(moduleName).

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

Liens vers un signal

La cible d'un lien ne doit pas nécessairement être seulement un presenter et une action, mais aussi un signal (ils appellent la méthode handle<Signal>()). La syntaxe est alors la suivante :

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

Le signal est donc distingué par un point d'exclamation :

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

Il est également possible de créer un lien vers le signal d'un sous-composant (ou sous-sous-composant) :

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

Liens dans un composant

Parce que les composants sont des unités autonomes et réutilisables qui ne devraient avoir aucun lien avec les presenters environnants, les liens fonctionnent un peu différemment ici. L'attribut Latte n:href et la balise {link} ainsi que les méthodes de composant comme link() et autres considèrent la cible du lien toujours comme le nom d'un signal. Par conséquent, il n'est même pas nécessaire d'inclure un point d'exclamation :

<a n:href="click">signal, pas une action</a>

Si nous voulions lier vers des presenters dans le template d'un composant, nous utiliserions la balise {plink} :

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

ou dans le code

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

Alias

Parfois, il peut être utile d'attribuer un alias facile à mémoriser à une paire Presenter:action. Par exemple, nommer la page d'accueil Front:Home:default simplement home ou Admin:Dashboard:default comme admin.

Les alias sont définis dans la configuration sous la clé application › aliases :

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

Dans les liens, ils sont ensuite écrits en utilisant un arobase, par exemple :

<a n:href="@admin">administration</a>

Ils sont également pris en charge dans toutes les méthodes fonctionnant avec des liens, comme redirect() et similaires.

Liens invalides

Il peut arriver que nous créions un lien invalide – soit parce qu'il mène à un presenter inexistant, soit parce qu'il passe plus de paramètres que la méthode cible n'en accepte dans sa signature, soit lorsqu'une URL ne peut pas être générée pour l'action cible. La manière de traiter les liens invalides est déterminée par la variable statique Presenter::$invalidLinkMode. Elle peut prendre une combinaison de ces valeurs (constantes) :

  • Presenter::InvalidLinkSilent – mode silencieux, le caractère # est retourné comme URL
  • Presenter::InvalidLinkWarning – un avertissement E_USER_WARNING est généré, qui sera enregistré en mode production, mais n'interrompra pas l'exécution du script
  • Presenter::InvalidLinkTextual – avertissement visuel, affiche l'erreur directement dans le lien
  • Presenter::InvalidLinkException – une exception InvalidLinkException est levée

Le paramètre par défaut est InvalidLinkWarning en mode production et InvalidLinkWarning | InvalidLinkTextual en mode développement. InvalidLinkWarning en environnement de production ne provoque pas l'interruption du script, mais l'avertissement sera enregistré. En environnement de développement, il est intercepté par Tracy et affiche un écran bleu. InvalidLinkTextual fonctionne en retournant un message d'erreur comme URL, commençant par les caractères #error:. Pour rendre ces liens visibles au premier coup d'œil, ajoutons à notre CSS :

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

Si nous ne voulons pas que des avertissements soient produits en environnement de développement, nous pouvons définir le mode silencieux directement dans la configuration.

application:
	silentLinks: true

LinkGenerator

Comment créer des liens avec un confort similaire à celui de la méthode link(), mais sans la présence d'un presenter ? C'est là qu'intervient Nette\Application\LinkGenerator.

LinkGenerator est un service que vous pouvez vous faire passer via le constructeur et ensuite créer des liens avec sa méthode link().

Il y a une différence par rapport aux presenters. LinkGenerator crée tous les liens directement comme des URL absolues. De plus, il n'y a pas de “presenter actuel”, il n'est donc pas possible de spécifier uniquement le nom de l'action comme cible link('default') ou d'utiliser des chemins relatifs vers les modules.

Les liens invalides lèvent toujours Nette\Application\UI\InvalidLinkException.

version: 4.0