# Ajouter des champs personnalisés au profil utilisateur WordPress

> Un client m'a demandé un champ « poste occupé » sur chaque fiche auteur. Voici comment l'afficher, l'enregistrer et le valider proprement.

- Auteur : Clément Hadrot
- Publié le : 2020-02-03
- Mis à jour le : 2020-02-03
- Catégorie : Tips
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tips/champs-personnalises-profil-utilisateur/

## L’essentiel

- show_user_profile affiche le champ
- personal_options_update l'enregistre
- Toujours valider avec un nonce

Un client d'agence immobilière m'a demandé, un vendredi après-midi, d'ajouter un numéro de carte professionnelle sur la fiche de chaque agent affichée sur le site. Rien d'exotique : un champ texte de plus dans l'écran « Profil » de l'administration. Sauf que WordPress ne propose pas de bouton magique pour ça, et qu'installer une extension pour un seul champ me semblait disproportionné.

La bonne nouvelle, c'est que l'API utilisateur de WordPress expose exactement les points d'entrée nécessaires : deux hooks pour afficher le champ, deux autres pour l'enregistrer selon que l'utilisateur modifie son propre profil ou celui d'un tiers. Voici la méthode complète, du formulaire à la validation.

## Afficher le champ sur l'écran de profil

Deux actions permettent d'injecter du HTML dans l'écran de profil : `show_user_profile` se déclenche quand l'utilisateur édite son propre compte, et `edit_user_profile` quand un administrateur édite le compte d'un autre. Il faut généralement accrocher les deux fonctions aux deux hooks pour couvrir tous les cas.

```
function agence_afficher_champ_carte_pro( $user ) {
    $carte = get_user_meta( $user->ID, 'carte_professionnelle', true );
    ?>
    <h3>Informations professionnelles</h3>
    <table class="form-table">
        <tr>
            <th><label for="carte_professionnelle">Carte professionnelle</label></th>
            <td>
                <input type="text" name="carte_professionnelle" id="carte_professionnelle"
                       value="<?php echo esc_attr( $carte ); ?>" class="regular-text" />
                <?php wp_nonce_field( 'maj_carte_pro', 'carte_pro_nonce' ); ?>
            </td>
        </tr>
    </table>
    <?php
}
add_action( 'show_user_profile', 'agence_afficher_champ_carte_pro' );
add_action( 'edit_user_profile', 'agence_afficher_champ_carte_pro' );
```

## Enregistrer et valider la valeur soumise

L'enregistrement suit le même principe : `personal_options_update` pour l'auto-édition, `edit_user_profile_update` pour l'édition d'un tiers. C'est le bon endroit pour vérifier le nonce et filtrer la valeur avant de l'enregistrer avec `update_user_meta()`.

> L'essentiel à retenir : show_user_profile affiche le champ ; personal_options_update l'enregistre ; Toujours valider avec un nonce

```
function agence_enregistrer_champ_carte_pro( $user_id ) {
    if ( ! isset( $_POST['carte_pro_nonce'] )
        || ! wp_verify_nonce( $_POST['carte_pro_nonce'], 'maj_carte_pro' ) ) {
        return;
    }
    if ( ! current_user_can( 'edit_user', $user_id ) ) {
        return;
    }
    $valeur = sanitize_text_field( wp_unslash( $_POST['carte_professionnelle'] ?? '' ) );
    update_user_meta( $user_id, 'carte_professionnelle', $valeur );
}
add_action( 'personal_options_update', 'agence_enregistrer_champ_carte_pro' );
add_action( 'edit_user_profile_update', 'agence_enregistrer_champ_carte_pro' );
```

Notez l'appel à `current_user_can( 'edit_user', $user_id )` : c'est ce qui empêche un utilisateur malintentionné de modifier le profil d'un autre en trafiquant manuellement une requête POST. Ne sautez jamais cette vérification, même pour un champ qui semble anodin.

## Restreindre l'affichage à un rôle donné

Dans le cas de l'agence immobilière, seuls les agents avaient besoin de ce champ ; il n'avait aucun sens sur le profil d'un simple rédacteur. Un test sur les rôles de l'utilisateur affiché permet d'éviter d'encombrer les autres écrans.

- Récupérer les rôles avec `$user->roles` (un tableau de slugs).
- Sortir de la fonction d'affichage si le rôle recherché est absent.
- Faire de même côté enregistrement, pour éviter d'écrire une meta inutile sur un autre rôle.

```
function agence_afficher_champ_carte_pro( $user ) {
    if ( ! in_array( 'agent_immobilier', (array) $user->roles, true ) ) {
        return;
    }
    // ... reste du code d'affichage
}
```

## Afficher la valeur côté site public

Une fois la meta enregistrée, l'afficher sur le site public se fait avec un simple `get_user_meta()`, typiquement dans un fichier `author.php` ou dans un bloc personnalisé si le thème est basé sur les blocs.

```
$carte = get_user_meta( get_the_author_meta( 'ID' ), 'carte_professionnelle', true );
if ( $carte ) {
    echo '<p>Carte professionnelle : ' . esc_html( $carte ) . '</p>';
}
```

> Sur ce type de champ, je préfère toujours préfixer la clé de meta avec le nom du projet (`agence_carte_professionnelle` plutôt que `carte_professionnelle`) pour éviter toute collision avec une extension installée plus tard.

## Variantes utiles

Le même schéma se décline facilement pour d'autres besoins courants :

- Un champ `select` pour une langue de contact préférée, avec une liste blanche de valeurs autorisées côté enregistrement.
- Une case à cocher « recevoir la newsletter interne », enregistrée en `1` ou supprimée avec `delete_user_meta()` si décochée.
- Un champ URL vers un profil LinkedIn, validé avec `esc_url_raw()` avant l'enregistrement.

## En résumé

Deux paires de hooks suffisent pour ajouter un champ de profil complet : `show_user_profile`/`edit_user_profile` pour l'affichage, `personal_options_update`/`edit_user_profile_update` pour l'enregistrement. Le nonce et la vérification de capacité ne sont pas optionnels : c'est ce qui transforme un simple champ en fonctionnalité réellement sécurisée. Pour ce client, le champ carte professionnelle vit toujours dans son thème sur mesure, sans la moindre extension dédiée.
