# 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.

- Auteur : Clément Hadrot
- Publié le : 2024-08-25
- Mis à jour le : 2024-08-25
- Catégorie : Tips
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tips/get-post-type-object-formulaire-metier/

## L’essentiel

- 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

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.
