Chapitre 7.3 — Custom Post Types & taxonomies
⏱️ TL;DR — Les Custom Post Types (CPT) permettent de modéliser n’importe quel contenu (livres, événements, produits, portfolios) avec, gratuitement, une interface d’admin, des URLs, la REST API et l’accès via
WP_Query. On les déclare avecregister_post_type()sur le hookinit, et on ajoute des taxonomies custom (register_taxonomy()) pour les classer. Deux options cruciales :show_in_rest(indispensable pour l’éditeur de blocs et le headless) etrewrite(les jolies URLs). Fil rouge : le CPTlivre.
🎯 Objectifs
- Déclarer un Custom Post Type avec les bonnes options.
- Déclarer une taxonomie custom et l’attacher au CPT.
- Comprendre
show_in_rest,supports,rewrite,capability_type. - Éviter les pièges (404, absence dans l’éditeur/REST).
1. Déclarer un CPT
Un CPT s’enregistre sur init :
add_action( 'init', 'wpr_books_register_cpt' );
function wpr_books_register_cpt() {
$labels = array(
'name' => __( 'Livres', 'wpr-books' ),
'singular_name' => __( 'Livre', 'wpr-books' ),
'add_new_item' => __( 'Ajouter un livre', 'wpr-books' ),
'edit_item' => __( 'Modifier le livre', 'wpr-books' ),
// …autres labels…
);
register_post_type( 'livre', array(
'labels' => $labels,
'public' => true, // visible sur le front + admin
'has_archive' => true, // /livres/ (archive)
'menu_icon' => 'dashicons-book',
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields' ),
'rewrite' => array( 'slug' => 'livres' ), // /livres/{slug}/
'show_in_rest' => true, // ⚠️ éditeur de blocs + REST/headless
'menu_position'=> 20,
) );
}public => true: accessible en front et listé en admin.supports: quelles fonctionnalités de l’éditeur (titre, contenu, image mise en avant, extrait, champs custom, révisions…).has_archive => true: crée une page d’archive/livres/.rewrite: la structure d’URL (ch. 5.9).menu_icon: une icône Dashicons dans le menu d’admin.
⚠️ Piège n°1 —
show_in_restoublié. Sansshow_in_rest => true, votre CPT s’édite avec l’ancien éditeur (pas Gutenberg) et n’apparaît pas dans la REST API → inutilisable en headless (Partie 9) et sans blocs. C’est le réglage à ne jamais oublier pour un CPT moderne.
⚠️ Piège n°2 — le 404 après création. Un CPT fraîchement déclaré renvoie 404 sur ses URLs tant que les rewrite rules ne sont pas régénérées :
flush_rewrite_rules()à l’activation du plugin (ch. 5.9 & 7.1), pas à chaque requête.
2. Déclarer une taxonomie custom
Pour classer les livres par genre :
add_action( 'init', 'wpr_books_register_taxo' );
function wpr_books_register_taxo() {
register_taxonomy( 'genre', array( 'livre' ), array(
'labels' => array(
'name' => __( 'Genres', 'wpr-books' ),
'singular_name' => __( 'Genre', 'wpr-books' ),
),
'public' => true,
'hierarchical' => true, // true = façon catégories ; false = façon étiquettes
'show_in_rest' => true, // éditeur + REST
'rewrite' => array( 'slug' => 'genre' ),
) );
}hierarchical => true: comme les catégories (arbre, cases à cocher).false: comme les étiquettes (mots-clés libres). Ch. 2.4.show_in_rest: même impératif que pour le CPT.- On obtient automatiquement : l’UI d’admin (métabox de sélection), les archives
/genre/{terme}/, l’accèsWP_Query/REST.
⚠️ Piège n°3 — l’ordre d’enregistrement. Enregistrez le CPT et la taxonomie tous deux sur
init. Si vous attachez une taxonomie à un CPT non encore déclaré, le lien peut échouer. En pratique, déclarez le CPT puis la taxonomie (ouregister_taxonomy_for_object_type()après coup).
3. Les options qui comptent
| Option | Effet |
|---|---|
public | Visible front + admin (raccourci pour plusieurs sous-options). |
show_in_rest | Éditeur de blocs + REST API (indispensable). |
supports | Fonctionnalités de l’éditeur (title, editor, thumbnail, excerpt, custom-fields, revisions, author, page-attributes). |
has_archive | Page d’archive du type. |
rewrite | Structure d’URL (slug). |
menu_icon, menu_position | Apparence dans le menu d’admin. |
capability_type | Base des capabilities (post par défaut, ou custom pour des droits dédiés). |
hierarchical | Pour un CPT « page-like » (parent/enfant). |
💡 Pour un dev React —
register_post_type()est une définition de modèle (comme unmodelPrisma ou un type de contenu Sanity) qui vous offre gratuitement : le CRUD d’admin, les routes/URLs, l’API REST (/wp-json/wp/v2/livre) et les requêtes. Vous décrivez quoi modéliser, WordPress génère l’infrastructure. En headless (Partie 9),show_in_rest: trueexpose immédiatement/wp/v2/livreque votre front Next.js consomme. C’est un énorme gain vs tout construire.
4. Métadonnées d’un CPT (aperçu)
Un livre a des données propres (ISBN, prix, auteur du livre…) : ce sont des métadonnées (post_meta), éditées via des metaboxes ou un panneau bloc, et exposables en REST — c’est tout le chapitre suivant (7.4).
5. Vérifier
- Après activation : voir le menu Livres en admin, créer un livre, vérifier l’URL
/livres/{slug}/(flush rewrite si 404). - Vérifier la présence dans la REST :
/wp-json/wp/v2/livredoit répondre (sinonshow_in_restmanquant). - Vérifier la taxonomie : la métabox Genres apparaît sur l’écran d’édition d’un livre, et
/genre/{terme}/fonctionne.
✏️ Exercices
- Vous créez un CPT
evenementque vous voulez éditable en blocs et consommable par une app Next.js. Quelle option est indispensable et pourquoi ? - « Genre » pour des livres : taxonomie hiérarchique ou plate ? Et « mots-clés » ?
- Après avoir déclaré
livre,/livres/dune/renvoie 404. Que faites-vous ?
✅ Solution
show_in_rest => true: sans elle, le CPT n’utilise pas l’éditeur de blocs et n’apparaît pas dans la REST API — donc inexploitable en headless (Next.js) ni en blocs.- « Genre » → hiérarchique (
true, façon catégories : structure fixe, cases à cocher). « Mots-clés » → plate (false, façon étiquettes : saisie libre). - Régénérer les rewrite rules : Réglages → Permaliens → Enregistrer, ou
flush_rewrite_rules()à l’activation du plugin (à faire une fois, pas à chaque requête).
🧠 Quiz de révision
1. Sur quel hook déclare-t-on un CPT ?
Sur init (via register_post_type).
2. À quoi sert show_in_rest ?
À rendre le CPT/la taxonomie éditable en blocs et présent dans la REST API (indispensable pour Gutenberg et le headless).
3. Que contrôle l’option hierarchical d’une taxonomie ?
Si elle se comporte comme les catégories (true, arborescente) ou les étiquettes (false, plate).
4. Qu’obtient-on gratuitement en enregistrant un CPT ?
L’admin (CRUD), les URLs/archives, la REST API et l’accès via WP_Query.
5. Pourquoi un nouveau CPT renvoie-t-il 404 sur ses URLs ?
Les rewrite rules ne sont pas régénérées ; il faut flush_rewrite_rules() (à l’activation).
Chapitre suivant : Métadonnées & metaboxes.