Trois hooks distincts, pas un seul, sont nécessaires pour ajouter un onglet fonctionnel à l’écran d’édition produit : un pour déclarer l’onglet, un pour afficher son contenu, un pour enregistrer les valeurs saisies. Le filtre woocommerce_product_data_tabs ne couvre que la première étape, ce qui explique pourquoi copier seulement cet extrait trouvé en ligne laisse souvent un onglet vide ou sans effet.
Déclarer l’onglet
Le filtre reçoit un tableau associatif de tous les onglets existants, chacun identifié par une clé unique et décrit par un sous-tableau contenant label, target et priority. La clé target correspond à l’identifiant HTML du panneau qui contiendra les champs, sans le caractère #.
add_filter( 'woocommerce_product_data_tabs', function( $tabs ) {
$tabs['wpm_business_data'] = array(
'label' => 'Données métier',
'target' => 'wpm_business_data_panel',
'class' => array(),
'priority' => 21,
);
return $tabs;
} );
La priorité place l’onglet parmi les onglets natifs, qui s’échelonnent globalement entre 10 et 100 environ selon leur position. Une priorité de 21 place ainsi le nouvel onglet juste après celui de l’inventaire, sans avoir besoin de connaître la valeur exacte de tous les onglets natifs environnants.
Afficher le panneau correspondant

L’affichage du contenu de l’onglet se fait via un second hook, woocommerce_product_data_panels, qui doit générer un élément HTML dont l’identifiant correspond exactement à la valeur de target déclarée précédemment.
add_action( 'woocommerce_product_data_panels', function() {
global $post;
echo '<div id="wpm_business_data_panel" class="panel woocommerce_options_panel">';
woocommerce_wp_text_input( array(
'id' => '_wpm_reference_interne',
'label' => 'Référence interne',
'desc_tip' => true,
'description' => 'Code utilisé par le service logistique.',
) );
echo '</div>';
} );
Les fonctions utilitaires comme woocommerce_wp_text_input() génèrent des champs déjà stylés de façon cohérente avec le reste de l’écran d’édition produit, sans avoir à reconstruire manuellement le balisage attendu par les feuilles de style d’administration de WooCommerce.
Enregistrer la valeur saisie
Sans une troisième étape, la valeur saisie dans le champ disparaît à chaque rechargement de la page : rien ne l’enregistre automatiquement. C’est le hook woocommerce_process_product_meta qui doit s’en charger, généralement lors de l’enregistrement du produit.
add_action( 'woocommerce_process_product_meta', function( $product_id ) {
if ( isset( $_POST['_wpm_reference_interne'] ) ) {
update_post_meta(
$product_id,
'_wpm_reference_interne',
sanitize_text_field( wp_unslash( $_POST['_wpm_reference_interne'] ) )
);
}
} );
L’erreur qu’on retrouve le plus souvent dans du code repris d’un tutoriel incomplet : le filtre des onglets et l’action d’affichage sont bien présents, mais rien n’enregistre la saisie. Le champ semble fonctionner à l’écran, jusqu’à ce qu’on recharge la page et qu’il apparaisse vide.
Un identifiant de panneau qui doit rester unique
La cohérence entre target et l’identifiant du panneau dépend d’une simple correspondance de chaînes de caractères, sans validation automatique par WooCommerce. Une faute de frappe entre les deux, ou un identifiant déjà utilisé par une autre extension installée sur la même boutique, provoque un onglet visible dans la liste mais dont le clic n’affiche jamais le bon contenu, sans qu’aucune erreur ne remonte dans les journaux.
Ce qu’il faut retenir
Ajouter un onglet fonctionnel à l’écran produit demande de coordonner trois hooks distincts : woocommerce_product_data_tabs pour le déclarer, woocommerce_product_data_panels pour afficher son contenu avec un identifiant correspondant exactement, et woocommerce_process_product_meta pour enregistrer effectivement la saisie. Omettre l’un des trois laisse un onglet qui semble fonctionner à l’écran sans jamais persister la moindre donnée.