Skip to Content
WordPressPartie 7 — Développer des pluginsCustom Post Types & taxonomies

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 avec register_post_type() sur le hook init, 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) et rewrite (les jolies URLs). Fil rouge : le CPT livre.

🎯 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_rest oublié. Sans show_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ès WP_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 (ou register_taxonomy_for_object_type() après coup).


3. Les options qui comptent

OptionEffet
publicVisible front + admin (raccourci pour plusieurs sous-options).
show_in_restÉditeur de blocs + REST API (indispensable).
supportsFonctionnalités de l’éditeur (title, editor, thumbnail, excerpt, custom-fields, revisions, author, page-attributes).
has_archivePage d’archive du type.
rewriteStructure d’URL (slug).
menu_icon, menu_positionApparence dans le menu d’admin.
capability_typeBase des capabilities (post par défaut, ou custom pour des droits dédiés).
hierarchicalPour un CPT « page-like » (parent/enfant).

💡 Pour un dev Reactregister_post_type() est une définition de modèle (comme un model Prisma 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: true expose immédiatement /wp/v2/livre que 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/livre doit répondre (sinon show_in_rest manquant).
  • Vérifier la taxonomie : la métabox Genres apparaît sur l’écran d’édition d’un livre, et /genre/{terme}/ fonctionne.

✏️ Exercices

  1. Vous créez un CPT evenement que vous voulez éditable en blocs et consommable par une app Next.js. Quelle option est indispensable et pourquoi ?
  2. « Genre » pour des livres : taxonomie hiérarchique ou plate ? Et « mots-clés » ?
  3. Après avoir déclaré livre, /livres/dune/ renvoie 404. Que faites-vous ?

✅ Solution

  1. 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.
  2. « Genre »hiérarchique (true, façon catégories : structure fixe, cases à cocher). « Mots-clés »plate (false, façon étiquettes : saisie libre).
  3. 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.