Création de liens URL

Créer des liens dans Nette est aussi facile que de pointer un doigt. Il suffit de pointer et le framework fera tout le travail pour vous. Nous allons vous montrer :

  • comment créer des liens dans les modèles et ailleurs
  • comment distinguer un lien de la page actuelle
  • qu'en est-il des liens invalides ?

Grâce au routage bidirectionnel, vous n'aurez jamais à coder en dur les URL des applications dans les modèles ou le code, qui peuvent changer ultérieurement ou être compliqués à composer. Il suffit de spécifier le présentateur et l'action dans le lien, de passer des 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 l'apprécier.

Dans le modèle de présentateur

Le plus souvent, nous créons des liens dans les modèles et l'attribut n:href est d'une grande aide :

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

Notez qu'au lieu de l'attribut HTML href, nous avons utilisé l'attribut n: n:href. Sa valeur n'est pas une URL, comme vous avez l'habitude de le faire avec l'attribut href, mais le nom du présentateur et de l'action.

Cliquer sur un lien revient, pour simplifier, à appeler une 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">detail</a>

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

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

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

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

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

Les paramètres dits persistants sont également transmis automatiquement dans les liens.

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

URL is: {link Home:default}

Dans le code

La méthode link() est utilisée pour créer un lien dans le présentateur :

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

Les paramètres peuvent également être transmis sous forme de 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 présentateur, en utilisant le LinkGenerator et sa méthode link().

Si la cible du lien est le présentateur et l'action, il a cette syntaxe :

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

Le format est pris en charge par toutes les balises Latte et toutes les méthodes du présentateur qui fonctionnent avec des liens, à savoir n:href, {link}, {plink}, link(), lazyLink(), isLinkCurrent(), redirect(), redirectPermanent(), forward(), canonicalize() et également LinkGenerator. Ainsi, même si n:href est utilisé dans les exemples, il pourrait s'agir de n'importe laquelle de ces fonctions.

La forme de base est donc Presenter:action:

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

Si nous établissons un lien avec l'action du présentateur actuel, nous pouvons omettre son nom :

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

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

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

Les liens peuvent également pointer vers d'autres modules. Ici, on distingue les liens relatifs aux sous-modules et les liens absolus. Le principe est analogue à celui des chemins d'accès aux disques, mais les deux-points remplacent les barres obliques. Supposons que le présentateur actuel fasse partie du module Front, nous écrirons alors :

<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 cas particulier est la liaison à lui-même. Ici, nous écrirons this comme cible.

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

Nous pouvons créer un lien vers une certaine partie de la page HTML par le biais de ce que l'on appelle un fragment après le symbole dièse # :

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

Chemins absolus

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

Pour générer une URL absolue, ajoutez deux barres obliques au début (par exemple, n:href="//Home:"). Vous pouvez aussi faire en sorte que le diffuseur ne génère que des liens absolus en définissant $this->absoluteUrls = true.

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

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

En même temps, tous les paramètres spécifiés dans la signature de l'élément action<Action>() ou render<View>() si la méthode action<Action>() n'est pas défini, sont transférés. Ainsi, si nous nous trouvons sur les pages Product:show et 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">refresh</a>

La fonction isLinkCurrent() détermine si la cible du lien est la même que la page actuelle. Cela peut être utilisé, par exemple, dans un modèle pour différencier les liens, etc.

Les paramètres sont les mêmes que pour la méthode link(), mais il est également possible d'utiliser le joker * au lieu d'une action spécifique, c'est-à-dire n'importe quelle action du présentateur.

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

Une forme abrégée peut être utilisée en combinaison avec n:href dans un seul élément :

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

Le caractère générique * remplace uniquement l'action du présentateur, pas le présentateur lui-même.

Pour savoir si nous sommes dans un certain module ou son sous-module, nous pouvons utiliser la fonction isModuleCurrent(moduleName).

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

La cible du lien peut être non seulement le présentateur et l'action, mais aussi le signal (ils appellent la méthode handle<Signal>()). La syntaxe est la suivante :

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

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

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

Vous pouvez également créer un lien vers le signal de la sous-composante (ou sous-sous-composante) :

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

Comme les composants sont des unités distinctes réutilisables qui ne doivent avoir aucune relation avec les présentateurs environnants, les liens fonctionnent un peu différemment. L'attribut Latte n:href et la balise {link} ainsi que les méthodes de composants telles que link() et autres considèrent toujours la cible comme le nom du signal. Il n'est donc pas nécessaire d'utiliser un point d'exclamation :

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

Si nous voulons créer un lien vers les présentateurs dans le modèle de composant, nous utilisons la balise {plink}:

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

ou dans le code

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

Il peut arriver que nous créions un lien invalide – soit parce qu'il fait référence à un présentateur inexistant, soit parce qu'il passe plus de paramètres que la méthode cible ne reçoit dans sa signature, soit lorsqu'il ne peut y avoir d'URL générée pour l'action ciblée. Ce qu'il faut faire avec les liens invalides est déterminé par la variable statique Presenter::$invalidLinkMode. Elle peut avoir l'une de ces valeurs (constantes) :

  • Presenter::InvalidLinkSilent – mode silencieux, renvoie le symbole # comme URL
  • Presenter::InvalidLinkWarning – E_USER_WARNING sera produit
  • Presenter::InvalidLinkTextual – avertissement visuel, le texte de l'erreur est affiché dans le lien
  • Presenter::InvalidLinkException – Une exception InvalidLinkException sera lancée.

La configuration par défaut en mode production est InvalidLinkWarning et en mode développement est InvalidLinkWarning | InvalidLinkTextual. InvalidLinkWarning ne tue pas le script dans l'environnement de production, mais l'avertissement sera enregistré. Dans l'environnement de développement, Tracy interceptera l'avertissement et affichera l'écran bleu d'erreur. Si l'adresse InvalidLinkTextual est définie, le présentateur et les composants renvoient le message d'erreur sous forme d'URL dont l'étoile est #error:. Pour rendre ces liens visibles, nous pouvons ajouter une règle CSS à notre feuille de style :

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

Si nous ne voulons pas que des avertissements soient produits dans l'environnement de développement, nous pouvons activer le mode de lien invalide silencieux dans la configuration.

application:
	silentLinks: true

Générateur de liens

Comment créer des liens avec le confort de la méthode link(), mais sans la présence d'un présentateur ? C'est pourquoi voici Nette\Application\LinkGenerator.

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

Il y a une différence par rapport aux présentateurs. LinkGenerator crée tous les liens sous forme d'URL absolus. De plus, il n'y a pas de “présentateur actuel”, il n'est donc pas possible de spécifier uniquement le nom de l'action link('default') ou les chemins relatifs vers les modules.

Les liens non valides provoquent toujours une erreur à l'adresse Nette\Application\UI\InvalidLinkException.

version: 4.0