Cette démarche enregistre une taxonomie personnalisée dans WordPress, votre propre regroupement de contenu à côté des catégories et des étiquettes, pour les développeurs qui ajoutent leur première taxonomie ou en réparent une qui fonctionne à moitié. Le problème habituel est une taxonomie visible dans wp-admin, mais sans panneau dans l’éditeur de blocs, ou dont les URL d’archive renvoient une erreur 404. La solution est une courte extension qui appelle register_taxonomy() sur le hook init avec show_in_rest activé et un slug d’URL clair, puis vide une seule fois les règles de permaliens. Vous terminez avec une taxonomie Region qui fonctionne dans l’éditeur, dans l’API REST et à ses propres URL d’archive.
Ce que vous allez accomplir
- Une taxonomie hiérarchique Region rattachée aux articles, enregistrée dans une petite extension pour qu’elle survive à un changement de thème.
- Un panneau Regions dans la barre latérale de l’éditeur de blocs, une colonne Regions dans la liste des articles et une route d’API REST (l’adresse
/wp-json/où l’éditeur de blocs lit les termes) à/wp-json/wp/v2/regions. - Des pages d’archive à des URL comme
/region/quebec/montreal/qui répondent avec un statut 200. - Le contrôle de qui peut créer des termes et de qui peut seulement les attribuer.
- Une série de vérifications WP-CLI répétables qui prouvent que chaque morceau fonctionne.
Prérequis
- WordPress 6.0 ou plus récent (7.x compris) et PHP 8.1 ou plus récent. Chaque argument utilisé ici existe depuis WordPress 5.5 ou avant, alors toutes les versions depuis se comportent de la même façon.
- Des permaliens lisibles activés sous Réglages > Permaliens (tout choix sauf Simple). Avec les permaliens simples, les archives fonctionnent quand même, mais seulement sous forme de chaîne de requête
?sh_region=montreal. - Un accès aux fichiers de
wp-content/plugins/par SSH, SFTP ou le gestionnaire de fichiers de votre hébergeur. - WP-CLI, la ligne de commande propre à WordPress, pour les vérifications, et jq (facultatif) pour rendre la sortie JSON lisible. Chaque étape indique aussi quoi regarder dans wp-admin si vous préférez le fureteur.
- Une copie de préproduction pour le premier essai. Enregistrer une taxonomie est sans danger, mais le vidage des permaliens touche toutes les URL du site.
Comment ça fonctionne
Une taxonomie est le bon outil quand les rédacteurs doivent classer les articles selon une région, une gamme de produits ou un public, et que les visiteurs ont besoin d’une page qui liste tout ce qui appartient à un groupe.
register_taxonomy() reçoit trois choses : un nom, les types de contenu auxquels la taxonomie se rattache et un tableau d’arguments. Le nom est la clé interne enregistrée à côté de chaque terme dans la base de données. Il doit compter 32 caractères ou moins, en minuscules, avec seulement des lettres, des chiffres, des traits d’union et des traits de soulignement. Un préfixe, comme dans sh_region, l’éloigne des noms que WordPress et les autres extensions utilisent déjà.
L’appel lui-même n’enregistre rien dans la base. Il indique à WordPress, pour la requête en cours seulement, que la taxonomie existe et comment elle doit se comporter. Voilà pourquoi il doit s’exécuter à chaque requête, sur le hook init, avant que WordPress analyse l’URL. L’article sur les hooks explique ce qui se passe quand un appel rate son hook. Vos termes restent dans la base de données, que la taxonomie soit enregistrée ou non. Retirez l’enregistrement et ils deviennent invisibles, sans être supprimés.
L’essentiel du travail se passe dans les arguments. Chacun active une surface, et celui qu’on oublie le plus souvent est show_in_rest. L’éditeur de blocs lit les taxonomies par l’API REST, alors une taxonomie absente de l’API n’obtient jamais de panneau dans l’éditeur.
Étapes
- Créez le fichier de l’extension. Les taxonomies décrivent votre contenu, pas votre design, alors elles vont dans une extension. Créez le dossier et le fichier :
mkdir -p wp-content/plugins/sh-regions
touch wp-content/plugins/sh-regions/sh-regions.php
Aucune sortie : les deux commandes ont fonctionné.
- Enregistrez la taxonomie sur
init. Mettez ceci danssh-regions.php:
<?php
/**
* Plugin Name: SH Regions
* Description: Adds a hierarchical Region taxonomy to posts.
* Text Domain: sh-regions
*/
add_action( 'init', 'sh_register_region_taxonomy' );
function sh_register_region_taxonomy() {
$labels = array(
'name' => __( 'Regions', 'sh-regions' ),
'singular_name' => __( 'Region', 'sh-regions' ),
'search_items' => __( 'Search Regions', 'sh-regions' ),
'all_items' => __( 'All Regions', 'sh-regions' ),
'parent_item' => __( 'Parent Region', 'sh-regions' ),
'parent_item_colon' => __( 'Parent Region:', 'sh-regions' ),
'edit_item' => __( 'Edit Region', 'sh-regions' ),
'update_item' => __( 'Update Region', 'sh-regions' ),
'add_new_item' => __( 'Add New Region', 'sh-regions' ),
'new_item_name' => __( 'New Region Name', 'sh-regions' ),
'menu_name' => __( 'Regions', 'sh-regions' ),
);
register_taxonomy(
'sh_region',
array( 'post' ),
array(
'labels' => $labels,
'hierarchical' => true,
'public' => true,
'show_admin_column' => true,
'show_in_rest' => true,
'rest_base' => 'regions',
'rewrite' => array(
'slug' => 'region',
'with_front' => false,
'hierarchical' => true,
),
)
);
}
Voici ce que fait chaque choix. hierarchical donne des termes parents et enfants avec des cases à cocher, comme les catégories; mettez-le à false pour une saisie libre, à la manière des étiquettes. show_in_rest ajoute le panneau de l’éditeur et la route de l’API, et rest_base nomme cette route. show_admin_column ajoute une colonne Regions dans Articles > Tous les articles. Dans rewrite, slug fixe la première partie de l’URL d’archive, with_front à false garde hors de l’URL tout préfixe de blogue comme /blog/, et le hierarchical intérieur place les termes parents dans le chemin.
Vérifiez la syntaxe du fichier avant que WordPress le charge :
php -l wp-content/plugins/sh-regions/sh-regions.php
No syntax errors detected in wp-content/plugins/sh-regions/sh-regions.php
- Videz les permaliens une seule fois, à l’activation. WordPress conserve une liste de modèles d’URL, appelés règles de réécriture, qu’il construit à partir de chaque type de contenu et de chaque taxonomie enregistrés. Une nouvelle taxonomie n’est pas dans cette liste tant qu’elle n’a pas été reconstruite. La reconstruction est lente : faites-la à l’activation et à la désactivation, jamais à chaque requête. Ajoutez ceci au même fichier :
register_activation_hook( __FILE__, 'sh_regions_activate' );
function sh_regions_activate() {
sh_register_region_taxonomy();
flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'sh_regions_deactivate' );
function sh_regions_deactivate() {
unregister_taxonomy( 'sh_region' );
flush_rewrite_rules();
}
La fonction d’activation appelle elle-même l’enregistrement, parce que l’extension n’était pas encore active quand init s’est déclenché pendant cette requête. Sans cette ligne, le vidage reconstruirait les règles sans votre taxonomie. La fonction de désactivation fait l’inverse : elle retire d’abord la taxonomie, pour que les règles reconstruites ne la contiennent plus. Activez maintenant l’extension :
wp plugin activate sh-regions
Plugin 'sh-regions' activated.
Success: Activated 1 of 1 plugins.
Dans le fureteur, Extensions > Extensions installées > Activer fait la même chose.
- Confirmez que WordPress voit la taxonomie.
wp taxonomy get sh_region --fields=name,label,object_type,hierarchical
Exemple de sortie :
+--------------+-----------+
| Field | Value |
+--------------+-----------+
| name | sh_region |
| label | Regions |
| object_type | ["post"] |
| hierarchical | 1 |
+--------------+-----------+
Error: Taxonomy sh_region doesn't exist. : WordPress ne connaît pas la taxonomie. Soit l’extension n’est pas active, soit le nom de la fonction contient une faute de frappe dans la ligne add_action().
- Ajoutez des termes et attachez-en un à un article. Créez un parent et un enfant.
--porcelainaffiche seulement l’identifiant du nouveau terme, dont vous avez besoin pour le parent :
wp term create sh_region 'Québec' --slug=quebec --porcelain
Exemple de sortie :
12
wp term create sh_region 'Montréal' --slug=montreal --parent=12 --porcelain
wp post term add 42 sh_region montreal
Exemple de sortie :
13
Success: Added term.
Utilisez vos propres identifiants : 12 est le parent créé par la première commande, et 42 représente n’importe quel article publié de votre site. Vous pouvez faire la même chose sous Articles > Regions et dans le panneau Regions de l’éditeur d’articles.
- Décidez qui gère les termes. Par défaut, quiconque peut gérer les catégories peut créer, modifier et supprimer des régions, et quiconque peut modifier des articles peut les attribuer. Autrement dit, les éditeurs et les administrateurs gèrent la liste, tandis que les auteurs et les contributeurs peuvent seulement y choisir. Pour le rendre explicite, ou pour resserrer l’accès, ajoutez un tableau
capabilitiesaux arguments :
'capabilities' => array(
'manage_terms' => 'manage_categories',
'edit_terms' => 'manage_categories',
'delete_terms' => 'manage_categories',
'assign_terms' => 'edit_posts',
),
Ces valeurs sont celles de WordPress par défaut. Pour que seuls les éditeurs et les rôles supérieurs puissent attribuer des régions, remplacez la valeur de assign_terms par edit_others_posts. Relancez php -l après la modification.
Vérifier que ça fonctionne
Vérifiez chaque surface promise par les arguments.
Le panneau de l’éditeur de blocs. Confirmez le réglage, puis ouvrez n’importe quel article :
wp eval 'var_dump( get_taxonomy( "sh_region" )->show_in_rest );'
bool(true)
Dans l’éditeur, l’onglet Article de la barre latérale contient maintenant un panneau Regions avec un arbre de cases à cocher. Québec y apparaît, avec Montréal en retrait en dessous.
La route REST.
curl -s https://example.com/wp-json/wp/v2/regions | jq -r '.[] | "\(.id) \(.slug) parent=\(.parent)"'
Exemple de sortie :
13 montreal parent=12
12 quebec parent=0
L’URL d’archive. Confirmez d’abord que la règle de réécriture existe, puis demandez la page :
wp rewrite list --match=/region/quebec/montreal/ --fields=match,query --format=csv
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/region/quebec/montreal/
Exemple de sortie, réduit à la première règle :
match,query
region/(.+?)/?$,index.php?sh_region=$matches[1]
200
La première règle listée est celle que WordPress utilise. Des règles génériques de pages peuvent la suivre, parce qu’elles correspondent à presque n’importe quel chemin. Une 404 avec une première règle correcte veut généralement dire qu’un cache de pages sert une ancienne réponse.
La colonne d’administration. Ouvrez Articles > Tous les articles. Une colonne Regions affiche Montréal sur l’article 42, et un clic sur le terme filtre la liste.
Dépannage
Aucun panneau Regions dans l’éditeur de blocs. show_in_rest est absent ou vaut false; sa valeur par défaut est false. Si vous avez rattaché la taxonomie à un type de contenu personnalisé, ce type a aussi besoin de show_in_rest => true, sinon il s’ouvre au complet dans l’éditeur classique. L’article sur les types de contenu personnalisés couvre ce côté.
Les URL d’archive renvoient une 404. Les règles de réécriture n’ont pas été reconstruites après l’enregistrement, ou le slug de rewrite a changé depuis la dernière reconstruction. Lancez wp rewrite flush, qui affiche Success: Rewrite rules flushed., ou ouvrez Réglages > Permaliens et cliquez sur Enregistrer les modifications sans rien changer. Si l’erreur persiste, vérifiez qu’aucune page ni aucun type de contenu n’utilise déjà le slug region.
La taxonomie n’apparaît jamais et le journal affiche un avis. Un nom de plus de 32 caractères fait refuser l’appel à register_taxonomy(). L’avis dans debug.log contient « Taxonomy names must be between 1 and 32 characters in length. » Raccourcissez le nom. Évitez aussi les noms de la liste des termes réservés de WordPress, comme year, author, type ou name. Ils entrent en conflit avec les requêtes du cœur et peuvent dérégler des pages publiques sans lien apparent.
Les termes ont disparu après un changement de thème. La taxonomie était enregistrée dans le functions.php de l’ancien thème. Les termes sont toujours dans la base de données : déplacez l’enregistrement dans une extension comme à l’étape 2 et ils reviennent. Vous pouvez confirmer qu’ils ont survécu avant de commencer :
wp db query "SELECT COUNT(*) FROM $(wp db prefix)term_taxonomy WHERE taxonomy = 'sh_region';"
Tout compte supérieur à 0 veut dire que les termes sont encore là.
Le panneau apparaît, mais la page d’archive utilise la mauvaise mise en page. WordPress cherche dans le thème taxonomy-sh_region-montreal.php, puis taxonomy-sh_region.php, puis taxonomy.php, puis archive.php. Les thèmes de blocs suivent le même ordre avec des gabarits .html dans templates/. Ajoutez taxonomy-sh_region.php (ou templates/taxonomy-sh_region.html) pour donner aux régions leur propre design.
Quand ce n’est pas la bonne approche
Une taxonomie sert à regrouper de nombreux articles sous des libellés communs. Si chaque valeur est propre à un seul article, comme un ISBN, un prix ou une date d’événement, stockez-la plutôt en métadonnée d’article (un champ personnalisé).
Si la liste de termes doit grimper dans les milliers parce que chaque nouvel élément ajoute un terme, revoyez d’abord la conception. L’article sur la performance des taxonomies personnalisées explique où ça commence à faire mal et quoi utiliser à la place.
Si deux types de contenu doivent pointer l’un vers l’autre avec leurs propres champs, comme des conférenciers liés à des conférences, il s’agit d’une relation entre types de contenu. Une taxonomie peut l’imiter, mais les pages de termes ne peuvent pas porter un contenu riche comme le font les articles.
Enfin, si les catégories intégrées conviennent déjà et que seul le libellé cloche, renommer le libellé du menu demande moins de travail qu’une nouvelle taxonomie. La référence officielle de register_taxonomy liste chaque argument et sa valeur par défaut.
Un WordPress qui rapporte vraiment mérite un opérateur — Stack Harbor opère cette pile sous WordPress Entreprise ; réservez une consultation d’infrastructure.