Les menus permettent aux éditeurs de gérer des liens ordonnés sans modifier un modèle de site. Un menu a un nom stable, comme primary ou footer, et un ensemble d’éléments distinct pour chaque menu traduit.
Créer un menu
Créez et organisez les menus dans Menus dans l’admin EmDash.
-
Cliquez sur Create Menu et entrez un nom et un libellé. Les modèles interrogent le nom. Le libellé identifie le menu dans l’admin, et certains modèles l’affichent aussi sur le site. Pour modifier le libellé plus tard, ouvrez le menu et cliquez sur le bouton crayon à côté de son titre.
-
Cliquez sur Add Content pour lier une entrée, ou sur Add Custom Link pour entrer une URL externe ou un chemin relatif à la racine du site.
-
Utilisez Move up et Move down pour définir l’ordre. Modifiez un élément et choisissez un Parent pour l’imbriquer.
-
Pour donner un style différent à un élément, modifiez-le et saisissez ses CSS classes, séparées par des espaces. Le modèle décide de l’effet de chaque classe. Par exemple, le modèle marketing affiche dans l’en-tête, sous forme de bouton, un élément de menu
primaryayant la classebutton.
Utilisez le même nom de menu dans chaque langue. Sur un site multilingue, ouvrez un menu et utilisez son panneau Translations pour créer et modifier les versions dans les autres langues. Chaque version linguistique a son propre libellé, de sorte que renommer un menu ne modifie que la version que vous éditez. EmDash garde les traductions du même contenu ou terme de taxonomie connectées, de sorte que getMenu() peut utiliser le libellé et le slug pour la langue demandée.
Comment les liens de menu sont résolus
Les éléments de menu de contenu et de taxonomie stockent une référence plutôt qu’une URL finie. Lorsqu’un modèle appelle getMenu(), EmDash résout cette référence en utilisant les données de la collection et de la langue actuelles.
| Type d’élément de menu | URL renvoyée au modèle |
|---|---|
| Entrée de contenu | Le urlPattern de la collection, ou /{collection}/{slug} lorsque la collection n’a pas de motif |
| Terme de taxonomie | /{taxonomy}/{slug} en utilisant la traduction du terme résolue |
| Archive de collection | /{collection}/ |
| Lien personnalisé | L’URL externe ou le chemin relatif à la racine entré par l’éditeur |
getMenu() omet un élément de contenu lorsqu’aucune des traductions de son entrée n’est publiée, par exemple parce que l’entrée est supprimée, dans la corbeille ou encore à l’état de brouillon. Une traduction dans la corbeille ou pas encore publiée compte comme absente, de sorte que l’élément se rabat sur une autre traduction. Lorsqu’un élément est omis, ses éléments enfants le sont avec lui. En mode édition, les éléments qui pointent vers des entrées non publiées restent dans le menu.
Chaque élément renvoyé contient aussi son libellé, sa cible optionnelle, son attribut de titre, ses classes CSS et ses children imbriqués. L’exemple de rendu ci-dessous utilise ces valeurs directement.
Rendre un menu
Appelez getMenu() dans un composant Astro rendu côté serveur. Il renvoie null lorsque le nom n’existe pas.
Le layout suivant rend un menu principal et un niveau d’éléments imbriqués :
---
import { getMenu } from "emdash";
import { getRelativeLocaleUrl } from "astro:i18n";
const locale = Astro.currentLocale;
const menu = await getMenu("primary", { locale });
function menuHref(url: string) {
return locale && url.startsWith("/")
? getRelativeLocaleUrl(locale, url)
: url;
}
---
{menu && menu.items.length > 0 && (
<nav aria-label="Navigation principale">
<ul>
{menu.items.map((item) => {
const href = menuHref(item.url);
return (
<li class:list={item.cssClasses}>
<a
href={href}
target={item.target}
rel={item.target === "_blank" ? "noopener noreferrer" : undefined}
title={item.titleAttr}
aria-current={Astro.url.pathname === href ? "page" : undefined}
>
{item.label}
</a>
{item.children.length > 0 && (
<ul>
{item.children.map((child) => {
const childHref = menuHref(child.url);
return (
<li class:list={child.cssClasses}>
<a
href={childHref}
target={child.target}
rel={child.target === "_blank" ? "noopener noreferrer" : undefined}
title={child.titleAttr}
aria-current={Astro.url.pathname === childHref ? "page" : undefined}
>
{child.label}
</a>
</li>
);
})}
</ul>
)}
</li>
);
})}
</ul>
</nav>
)}
getMenu() choisit d’abord la locale explicite, puis la langue de la requête actuelle, puis la langue par défaut configurée. Si un menu ou une entrée référencée est manquante dans cette langue, la recherche suit la chaîne de repli configurée.
Les URLs des éléments de menu contiennent le motif d’URL de la collection ou le chemin de taxonomie, mais elles ne contiennent pas le préfixe de langue d’Astro. Le helper menuHref() ajoute ce préfixe aux liens relatifs à la racine et laisse les liens externes inchangés.
L’exemple rend un niveau enfant, ce qui couvre un menu déroulant typique. Si les éditeurs peuvent créer une navigation plus profonde, déplacez le balisage de l’élément dans un composant récursif qui rend les children de chaque élément avec les mêmes règles.
Utiliser les menus dans les zones de widgets
Un widget de menu place un menu existant dans une zone de widgets. Le widget lit le menu pour la langue de la requête actuelle. Utilisez le patron de rendu direct ci-dessus lorsque le site a besoin d’un balisage imbriqué personnalisé ou d’une gestion explicite des URLs par langue.
Interroger les données de menu directement
Utilisez getMenus() lorsqu’un modèle a besoin des définitions de menu disponibles plutôt que des éléments d’un seul menu. La référence de l’API runtime documente les signatures de requête et les valeurs de retour.
Pour les modifications programmatiques de menus, authentifiez-vous avec un token Bearer et ajoutez X-EmDash-Request: 1 à chaque requête modifiant l’état. Voir les endpoints de menu pour les corps de requête et les réponses.
Voir Internationalisation pour la configuration du routage linguistique et du repli.