Aller au contenu

Menus de navigation

Les menus de navigation permettent de structurer la navigation de votre site. ArtisanCMS offre un constructeur de menus visuel avec support de la hiérarchie, plusieurs emplacements prédéfinis et un cache automatique.

Le modèle Menu (App\Models\Menu) représente un menu complet :

ChampTypeDescription
namestringNom du menu
slugstringIdentifiant unique
locationstringEmplacement (header, footer, sidebar, custom)
site_idintegerSite associé (multi-site)
is_activebooleanMenu actif ou inactif

Le modèle MenuItem (App\Models\MenuItem) représente un élément individuel du menu :

ChampTypeDescription
menu_idintegerMenu parent
parent_idintegerÉlément parent (sous-menus)
titlestringTexte affiché
typestringType de lien
reference_idintegerID du contenu lié (nullable)
urlstringURL personnalisée (nullable)
targetstringCible du lien (_self, _blank)
css_classstringClasses CSS additionnelles
orderintegerPosition dans le menu

ArtisanCMS propose quatre emplacements de menu prédéfinis :

EmplacementUtilisation typique
headerNavigation principale en haut de page
footerLiens du pied de page
sidebarNavigation latérale
customEmplacement libre pour les thèmes

Chaque emplacement peut contenir un seul menu actif à la fois.

Les éléments de menu supportent plusieurs types de liens :

MenuItem::create([
'type' => 'page',
'reference_id' => $page->id,
'title' => $page->title,
]);

L’URL est automatiquement mise à jour si le slug de la page change.

MenuItem::create([
'type' => 'post',
'reference_id' => $post->id,
'title' => $post->title,
]);
MenuItem::create([
'type' => 'category',
'reference_id' => $term->id,
'title' => $term->name,
]);
MenuItem::create([
'type' => 'custom',
'url' => 'https://example.com',
'title' => 'Lien externe',
'target' => '_blank',
]);

Les éléments de menu supportent l’imbrication via le champ parent_id pour créer des sous-menus :

Menu principal
├── Accueil
├── Services
│ ├── Consulting
│ ├── Formation
│ └── Support
├── Blog
└── Contact

L’interface d’administration permet de réorganiser les éléments par drag-and-drop et de les imbriquer visuellement.

Le Admin\MenuController gère les opérations sur les menus :

Route::resource('menus', MenuController::class);
Route::post('menus/{menu}/items', [MenuController::class, 'storeItem']);
Route::put('menus/{menu}/items/{item}', [MenuController::class, 'updateItem']);
Route::delete('menus/{menu}/items/{item}', [MenuController::class, 'destroyItem']);
Route::post('menus/{menu}/reorder', [MenuController::class, 'reorder']);

Le MenuService encapsule la logique métier :

class MenuService
{
public function getMenuByLocation(string $location): ?Menu;
public function getMenuTree(Menu $menu): Collection;
public function reorderItems(Menu $menu, array $order): void;
public function duplicateMenu(Menu $menu): Menu;
}

Les menus sont mis en cache automatiquement pour éviter des requêtes répétées à chaque chargement de page. Le MenuObserver se charge d’invalider le cache lorsqu’un menu ou un élément est modifié :

class MenuObserver
{
public function saved(Menu $menu): void
{
Cache::tags(['menus', "site:{$menu->site_id}"])->flush();
}
public function deleted(Menu $menu): void
{
Cache::tags(['menus', "site:{$menu->site_id}"])->flush();
}
}

Le cache est également invalidé lors de la modification d’un MenuItem pour garantir la cohérence des données affichées.

Pour afficher un menu dans un template Blade :

@php
$menu = app(MenuService::class)->getMenuByLocation('header');
$items = app(MenuService::class)->getMenuTree($menu);
@endphp
<nav>
@foreach($items as $item)
<a href="{{ $item->url }}" target="{{ $item->target }}">
{{ $item->title }}
</a>
@endforeach
</nav>

Les thèmes ArtisanCMS incluent des composants Blade prêts a l’emploi pour le rendu des menus avec support des sous-menus.