# add_menu_page et add_submenu_page : organiser l’admin d’une extension

> Cinq écrans à ranger dans le menu d'admin d'une extension de facturation, sans écraser le premier sous-menu ni entrer en collision avec une icône déjà prise. La recette qui marche à chaque fois.

- Auteur : Clément Hadrot
- Publié le : 2021-12-29
- Mis à jour le : 2021-12-29
- Catégorie : Extensions
- URL : https://wpmoderne.dev.wordpress-developpement.fr/extensions/add-menu-page-add-submenu-page-organiser-admin/

## L’essentiel

- Le premier appel à add_submenu_page renomme automatiquement le premier sous-menu
- La position numérique d'un menu accepte les décimales pour s'insérer entre deux entrées existantes
- Chaque sous-menu peut exiger sa propre capacité, indépendamment du menu parent

Un plugin de facturation développé pour une coopérative agricole devait proposer cinq écrans distincts dans l'admin : factures, clients, produits, réglages de TVA, et export comptable. Sans organisation réfléchie, cinq entrées côte à côte dans le menu principal de WordPress deviennent vite illisibles. Voici comment j'ai structuré ce menu avec `add_menu_page` et `add_submenu_page`.

## Créer le menu principal

```
add_action( 'admin_menu', 'cooperative_ajouter_menu_facturation' );

function cooperative_ajouter_menu_facturation() {
    add_menu_page(
        'Facturation',
        'Facturation',
        'manage_facturation',
        'cooperative-facturation',
        'cooperative_afficher_page_factures',
        'dashicons-media-spreadsheet',
        26
    );
}
```

La position 26 place le menu juste après « Commentaires » (position 25) et avant « Apparence » (position 60), un emplacement qui a semblé naturel à l'équipe comptable de la coopérative, habituée à des menus classés par fréquence d'utilisation plutôt que par ordre alphabétique.

## Le piège du premier sous-menu

Un comportement peu documenté surprend presque tous les développeurs la première fois : le tout premier appel à `add_submenu_page` pour un menu donné ne crée pas un nouveau sous-menu, il renomme le sous-menu automatiquement généré qui porte, par défaut, le même intitulé que le menu principal.

> L'essentiel à retenir : Le premier appel à add_submenu_page renomme automatiquement le premier sous-menu ; La position numérique d'un menu accepte les décimales pour s'insérer entre deux entrées existantes ; Chaque sous-menu peut exiger sa propre capacité, indépendamment du menu parent

```
add_submenu_page(
    'cooperative-facturation',
    'Factures',
    'Factures',
    'manage_facturation',
    'cooperative-facturation',   // même slug que le menu parent
    'cooperative_afficher_page_factures'
);

add_submenu_page(
    'cooperative-facturation',
    'Clients',
    'Clients',
    'manage_facturation',
    'cooperative-facturation-clients',
    'cooperative_afficher_page_clients'
);
```

En réutilisant le même slug (`cooperative-facturation`) que le menu parent pour ce premier appel, le sous-menu affiché s'intitule « Factures » plutôt que de dupliquer inutilement « Facturation ». C'est une convention à connaître, pas un bug : sans elle, on se retrouve souvent avec un sous-menu fantôme au libellé redondant.

## Des capacités différentes par écran

Toutes les personnes autorisées à consulter les factures ne devaient pas nécessairement accéder aux réglages de TVA, réservés au trésorier de la coopérative. Chaque sous-menu peut recevoir sa propre capacité, indépendamment de celle du menu parent.

```
add_submenu_page(
    'cooperative-facturation',
    'Réglages TVA',
    'Réglages TVA',
    'manage_reglages_facturation',
    'cooperative-facturation-tva',
    'cooperative_afficher_page_reglages_tva'
);
```

Ces capacités personnalisées, `manage_facturation` et `manage_reglages_facturation`, ne sont pas fournies nativement par WordPress : elles doivent être ajoutées explicitement à un rôle via `add_cap()`, généralement lors de l'activation de l'extension, pour un rôle existant comme `administrator` ou pour un rôle personnalisé créé pour l'occasion.

```
function cooperative_ajouter_capacites() {
    $role = get_role( 'administrator' );
    if ( $role ) {
        $role->add_cap( 'manage_facturation' );
        $role->add_cap( 'manage_reglages_facturation' );
    }
}
register_activation_hook( __FILE__, 'cooperative_ajouter_capacites' );
```

## Choisir une icône qui ne fait pas doublon

Le paramètre d'icône accepte une classe Dashicons (`dashicons-media-spreadsheet` dans cet exemple), l'URL d'une image, ou une chaîne `data:image/svg+xml;base64,...` pour un SVG personnalisé encodé directement. Un choix mal réfléchi produit rapidement un menu d'admin où deux extensions différentes affichent visuellement la même icône, source de confusion pour l'équipe cliente.

- Parcourir la liste officielle des Dashicons avant de choisir, pour éviter une icône déjà largement utilisée par des extensions courantes
- Un SVG personnalisé encodé en base64 hérite automatiquement de la couleur du thème d'administration actif, contrairement à une image PNG classique
- La position numérique accepte des valeurs décimales (comme `26.5`) pour s'insérer précisément entre deux entrées déjà occupées par d'autres extensions

## Vérifier l'onglet actif correctement

Un dernier détail négligé donnait, dans une première version, un onglet « Factures » qui restait visuellement actif même en naviguant vers « Clients ». La cause : le slug de page utilisé par WordPress pour déterminer l'onglet actif se base sur le paramètre `page` de l'URL, comparé au slug déclaré, pas sur un état interne à gérer manuellement. Une fois les slugs de chaque sous-menu correctement différenciés (`cooperative-facturation-clients`, et non une réutilisation accidentelle du même slug), le problème a disparu de lui-même.

## Pour aller plus loin

`add_menu_page` et `add_submenu_page` restent des fonctions simples en apparence, mais leurs quelques conventions implicites (renommage du premier sous-menu, gestion des capacités, choix de position) méritent d'être maîtrisées avant de structurer l'admin d'une extension à plusieurs écrans. Une fois ces règles connues, organiser cinq, dix ou vingt écrans d'administration devient un exercice répétitif plutôt qu'une source récurrente de bugs visuels.
