Le WordPress d'aujourd'hui, décodé pour les développeurs

Tips

get_post_type_object pour adapter un formulaire selon le métier du client

Une même extension sert plusieurs métiers avec des champs différents. get_post_type_object permet d'adapter dynamiquement un formulaire d'édition sans dupliquer le code par type de contenu.

Par Clément Hadrot • 25 août 2024 • 5 min de lecture • Aucun commentaire
get_post_type_object pour adapter un formulaire selon le métier du client

Comment afficher des champs différents dans un même formulaire d’édition sans dupliquer six fois le même fichier ? C’est la question qu’une agence spécialisée dans les sites pour indépendants m’a posée après avoir constaté que son thème mutualisé comptait déjà quatre copies quasi identiques d’un même formulaire de fiche, une par métier accompagné : coach, ostéopathe, avocat, architecte d’intérieur.

La fonction get_post_type_object() résout élégamment ce problème : elle retourne l’objet complet d’un type de contenu, avec son slug, ses arguments d’enregistrement, et surtout la possibilité d’y attacher des propriétés personnalisées qui pilotent l’affichage du formulaire. Voici comment cette agence a réduit son code de moitié.

Attacher une configuration de champs à chaque type de contenu

Plutôt que de coder en dur la liste des champs par type, on enregistre chaque type de contenu avec un argument personnalisé ch_champs_metier, un tableau qui décrit les champs à afficher. Cet argument n’est pas standard dans WordPress, mais l’API d’enregistrement des types de contenu accepte n’importe quelle clé supplémentaire, qui sera simplement stockée dans l’objet retourné par get_post_type_object().

register_post_type( 'fiche_coach', array(
    'label'        => 'Fiches coach',
    'public'       => true,
    'supports'     => array( 'title', 'editor' ),
    'ch_champs_metier' => array(
        'tarif_horaire'    => 'Tarif horaire (€)',
        'specialites'      => 'Spécialités',
        'certifications'   => 'Certifications',
    ),
) );

register_post_type( 'fiche_osteopathe', array(
    'label'        => 'Fiches ostéopathe',
    'public'       => true,
    'supports'     => array( 'title', 'editor' ),
    'ch_champs_metier' => array(
        'conventionnement' => 'Conventionnement',
        'specialites'      => 'Spécialités',
        'urgences'         => 'Prend les urgences',
    ),
) );
L'essentiel à retenir : Un seul formulaire lit les métadonnées du type de contenu courant ; Les champs affichés dépendent d'un tableau de configuration par type ; Aucune duplication de gabarit entre les métiers

Un seul formulaire qui lit cette configuration

La métabox d’édition devient générique : elle récupère le type de contenu courant avec get_post_type(), va chercher son objet complet avec get_post_type_object(), puis parcourt le tableau ch_champs_metier pour générer les champs correspondants. Aucun métier n’a besoin de son propre fichier de formulaire.

function ch_render_metabox_metier( $post ) {
    $type_objet = get_post_type_object( get_post_type( $post ) );

    if ( empty( $type_objet->ch_champs_metier ) ) {
        return;
    }

    foreach ( $type_objet->ch_champs_metier as $cle => $label ) {
        $valeur = get_post_meta( $post->ID, $cle, true );
        printf(
            '<p><label>%1$s<br /><input type="text" name="ch_champ[%2$s]" value="%3$s" /></label></p>',
            esc_html( $label ),
            esc_attr( $cle ),
            esc_attr( $valeur )
        );
    }
}

Enregistrer les champs sans connaître leur liste à l’avance

L’enregistrement suit la même logique : on relit la configuration du type de contenu pour ne traiter que les clés autorisées, ce qui évite d’enregistrer un champ non prévu envoyé par une requête malformée.

add_action( 'save_post', function ( $post_id ) {
    $type_objet = get_post_type_object( get_post_type( $post_id ) );

    if ( empty( $type_objet->ch_champs_metier ) || empty( $_POST['ch_champ'] ) ) {
        return;
    }

    foreach ( array_keys( $type_objet->ch_champs_metier ) as $cle ) {
        if ( isset( $_POST['ch_champ'][ $cle ] ) ) {
            update_post_meta( $post_id, $cle, sanitize_text_field( $_POST['ch_champ'][ $cle ] ) );
        }
    }
} );

Ce que cette organisation change concrètement

  • Ajouter un septième métier revient à ajouter un bloc register_post_type, jamais à toucher au code du formulaire.
  • Une correction de sécurité ou d’affichage se fait une seule fois, dans la métabox générique, au lieu d’être répétée dans chaque copie.
  • Le tableau ch_champs_metier peut être complété avec un type de champ (texte, case à cocher, liste déroulante) pour affiner encore l’affichage, sans changer la structure globale.

Une limite à ne pas ignorer

Cette approche générique perd en lisibilité si les types de champs deviennent trop différents d’un métier à l’autre : listes déroulantes avec options dynamiques, champs répétables, validations spécifiques. Passé un certain niveau de complexité, un outil de champs personnalisés plus complet devient pertinent, mais pour six à dix champs texte ou case à cocher par métier, cette solution native reste largement suffisante et ne rajoute aucune dépendance.

Mutualiser un formulaire ne veut pas dire l’appauvrir : c’est déplacer la variabilité du code vers la configuration, là où elle est plus facile à faire évoluer.

Ce mécanisme ne traite pas la création des types de contenu eux-mêmes, qui reste un travail préalable d’architecture selon les métiers réellement accompagnés par l’agence : c’est une étape distincte, à mener avant d’attaquer la mutualisation du formulaire.

Pour aller plus loin

La fonction get_post_type_object() est documentée sur developer.wordpress.org et mérite d’être explorée au-delà de cet usage : elle donne également accès aux libellés, aux capacités et aux règles de réécriture d’URL du type de contenu, autant d’informations réutilisables dans des formulaires génériques similaires ailleurs dans une extension.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi