Ajouter des champs meta aux produits WooCommerce

La célèbre extension e-commerce WordPress propose nativement bon nombre de champs produits. Prix, UGS, stock, attributs, poids, dimensions… De quoi couvrir pas mal de possibilités !

Mais que faire si vous créez une boutique e-commerce où les produits possèdent une donnée très spécifique ? Découvrons ici la deuxième partie de notre tutoriel et ajoutons des champs meta aux produits WooCommerce.

Si vous avez manquez la première partie de ce tutoriel, il est préférable de le lire pour apprendre à ajouter un onglet sur les pages produits WooCommerce.

L’intégralité du thème créé dans cette série de tutoriels est téléchargeable librement ici. Notez que le thème mosaikafifteen est enfant de twentyfifteen, il est donc nécessaire d’avoir ce dernier dans votre dossier /themes.

Créer un onglet WooCommerce et ajouter des champs aux produits
Fonctionnement général de l’outil créé

Pour faire le point, reprenons rapidement notre premier tutoriel. L’idée est de pouvoir enregistrer des « J’aime » et « Je déteste » sur chaque produit. Chaque clic sur un bouton augmentera une valeur meta du produit de 1. Ces valeurs de loves et hates seront enregistrées dans un champ meta du produit créé sur-mesure et affiché dans l’onglet Avancé de WooCommerce.

Pour l’instant, nous avons donc :

  1. ajouté un nouvel onglet sur la page publique (en front-end) d’un produit
  2. relié le contenu de cet onglet à la fonction wc_get_template() afin d’externaliser le template du contenu de l’onglet dans un fichier woocommerce/single-product/tabs/love-product.php
  3. créé le template en question (mais nous l’aborderons plus en détails ci-dessous)

Bref, c’est bien beau d’afficher des données à l’utilisateur, mais encore faut-il que l’administrateur puisse les éditer via l’admin d’une fiche produit. Mais aussi que ces nouvelles données soient enregistrées correctement dans la base de données WordPress.

Procédons alors par étapes. Cette fois, nous aborderons :

  1. les différents endroits où il est possible d’ajouter des champs dans l’administration d’un produit WooCommerce
  2. l’ajout à proprement parlé de champs meta personnalisés
  3. l’enregistrement des valeurs des nouveaux champs
  4. et enfin, la mise en relation entre les boutons J’aime et Je déteste et la base de données WordPress

Prêt ? Bouclez vos ceintures, souquez les artimuses et rentrons dans le vif du sujet !

Comment ajouter des custom metas aux produits WooCommerce

Ajouter des champs custom post meta aux produits WooCommerce

Prenons d’abord le temps de nous pencher un peu sur le cœur de WooCommerce. C’est le fichier includes/admin/meta-boxes/class-wc-meta-box-product-data.php qui contient le code en charge de créer les metaboxes propres à WooCommerce sur la page d’administration d’un produit.

Notez deux choses importantes dans ce fichier.

1. Des fonctions pour générer les tags d’inputs

Plutôt que d’avoir à se répéter et écrire des <input /> en pagaille, WooCommerce simplifie la génération des balises des labels et de leurs inputs de type :

  • text avec woocommerce_wp_text_input()
  • textarea avec woocommerce_wp_textarea_input()
  • checkbox avec woocommerce_wp_checkbox()
  • radio avec woocommerce_wp_radio()
  • select avec woocommerce_wp_select()
  • hidden avec woocommerce_wp_hidden_input()

Le code ci-dessous vous permettra de générer un exemple de chaque type de champ possible afin de vous repérer.

/*************************************************************************************************
* On ajoute des champs de test pour se repérer, dans l'onglet Général
* Résultat visuel : http://img.saika.li/bWk6
*************************************************************************************************/
function msk_add_test_field_data() {
	echo '<div style="background:#f8fbca; padding:1em;">';

	echo '<h4>Testons les différents types de champs</h4>';

	// Champ de type text
	woocommerce_wp_text_input(
		array(
			'id' => 'input_text', 
			'label' => __('Champ de type "text"', 'msk'),
			'placeholder' => __('Placeholder du champ text', 'msk'),
			'description' => __('La description peut apparaître dans une infobulle si "desc_tip" est sur "true".', 'msk'),
			'desc_tip' => true // Si "true", la description s'affichera en infobulle
		)
	);

	// Champ de type hidden
	woocommerce_wp_hidden_input(
		array(
			'id' => 'input_hidden', 
			'label' => __('Champ de type "hidden"', 'msk'),
			'value' => 'valeur-du-champ-hidden',
		)
	);

	// Champ de type textarea
	woocommerce_wp_textarea_input(
		array(
			'id' => 'input_textarea', 
			'label' => __('Champ de type "textarea"', 'msk'),
			'class' => 'widefat',
			'placeholder' => __('Placeholder du champ textarea', 'msk'),
			'description' => __('<br>La description n\'apparaîtra pas dans une infobulle si "desc_tip" est sur "false" ou inexistant.', 'msk'),
			'custom_attributes' => array( // Un tableau d'attributs personnalisés qui seront ajoutés au champ en question
				'data-test' => 50,
				'data-other-test' => 'Lorem ipsum'
			)
		)
	);

	// Champ de type checkbox
	woocommerce_wp_checkbox(
		array(
			'id' => 'input_checkbox', 
			'label' => __('Champ de type "checkbox"', 'msk'),
			'value' => 'yes', // La valeur enregistrée de la checkbox
			'cbvalue' => 'yes',  // La valeur de la checkbox en question. Si elle est la même que "value", la checkbox sera cochée
		)
	);

	// Champ de type select
	woocommerce_wp_select(
		array(
			'id' => 'input_select', 
			'label' => __('Champ de type "select"', 'msk'),
			'options' => array( // Un tableau avec les options (value et nom) du select
				'value1' => 'Am',
				'value2' => 'Stram',
				'value3' => 'Gram',
			),
			'value' => 'value2', // La valeur enregistrée, choisie, de la select
		)
	);

	// Champ de type radio
	woocommerce_wp_radio(
		array(
			'id' => 'input_radio', 
			'label' => __(' ', 'msk'),
			'options' => array( // Un tableau avec les options (value et nom) du radio
				'value4' => 'Pif',
				'value5' => 'Paf',
				'value6' => 'Pouf',
			),
			'value' => 'value5', // La valeur enregistrée, choisie, de la radio
		)
	);

	echo '</div>';
}
add_action('woocommerce_product_options_general_product_data', 'msk_add_test_field_data');

Et résultera en…

La liste des différents champs possibles avec les fonctions helper de WooCommerce
La liste des différents champs possibles avec les fonctions helper de WooCommerce

Notez que ces fonctions de génération de champs woocommerce_wp_* proposent par défaut la valeur de la meta du produit équivalente à l’id du champ défini. Pour prendre exemple : WooCommerce ne définit pas d’arguments value lorsqu’il enregistre bon nombre de ces champs, mais donne directement en argument id la clé meta du champ en question, comme :
_manage_stock pour la valeur de la gestion du stock
_regular_price pour la valeur du prix normal
_sale_price pour la valeur du prix en promo
Ainsi, le champ sera automatiquement pré-rempli de la valeur meta en question (chargée via get_post_meta), sans avoir besoin de définir un argument value.

2. De nombreuses actions pour s’interfacer

Toujours en parcourant le fichier class-wc-meta-box-product-data.php, vous découvrirez plus de 25 occurrences de la fonction do_action(). Ce sont donc autant d’endroits où nous pouvons nous interfacer pour ajouter des champs où bon nous semble.

L’exemple général proposé précédemment ajoutait des champs produits dans l’onglet Général via l’action woocommerce_product_options_general_product_data. Le nom de chacune de ces actions étant assez explicite, il devient alors facile d’ajouter du contenu — et surtout nos champs ! — dans la metabox de WooCommerce, par exemple :

  • en fin d’onglet Inventaire avec l’action woocommerce_product_options_inventory_product_data
  • en fin d’onglet Livraison avec l’action woocommerce_product_options_shipping
  • en fin d’onglet Produits liés avec l’action woocommerce_product_options_related
  • en fin d’onglet Attributs avec l’action woocommerce_product_options_attributes
  • en fin d’onglet Avancé avec l’action woocommerce_product_options_advanced
  • après le champ UGS avec l’action woocommerce_product_options_sku
  • après les champs de prix avec l’action woocommerce_product_options_pricing
  • après la checkbox de gestion de stock avec l’action woocommerce_product_options_stock

Ajouter un champ dans l’onglet « Avancé »

Nous voila en mesure d’ajouter nos champs J’aime et Je déteste qui stockeront le nombre d’amour et de haine qu’a reçu un produit. On reprend donc les fonctions helpers et les actions présentées précédemment.

/*************************************************************************************************
* On ajoute 2 champs (post meta ou custom field) aux produits WC dans l'onglet "Avancé"
*************************************************************************************************/
function msk_add_loves_hates_fields_to_product() {
	woocommerce_wp_text_input(
		array(
			'id' => 'loves', 
			'data_type' => 'decimal', 
			'label' => __('Loves', 'msk'),
			'placeholder' => __('Amount of love', 'msk'),
			'description' => __('Love this product has received.', 'msk'),
			'desc_tip' => true
		)
	);

	woocommerce_wp_text_input(
		array(
			'id' => 'hates', 
			'data_type' => 'decimal', 
			'label' => __('Hates', 'msk'),
			'placeholder' => __('Amount of hate', 'msk'),
			'description' => __('Hatred this product has received.', 'msk'),
			'desc_tip' => true
		)
	);
}
add_action('woocommerce_product_options_advanced', 'msk_add_loves_hates_fields_to_product');

Résultera en…

Nos nouveaux champs produits WooCommerce !
Nos nouveaux champs produits WooCommerce !

Nous voila donc en possession de deux nouveaux champs texte dans l’administration de nos produits WooCommerce. Mais attention, vous pourrez essayer de changer leurs valeurs et enregistrer le produit en question, cette valeur ne sera pas sauvegardée.

Il faut désormais indiquer à WordPress l’existence de ces champs et lui dire quoi en faire lorsque l’on enregistre un post.

Enregistrer les données des nouveaux champs

Avec l’action save_post, nous allons vérifier si le post en cours d’enregistrement (à la création ou à sa mise à jour) est bien de type produit product.

Si c’est le cas, et si nos champs loves et hates sont existants dans les valeurs reçues, nous enregistrons les dites valeurs dans des métadonnées du produit, nommées loves et hates.

/*************************************************************************************************
* On enregistre les valeurs de LOVES & HATES lorsqu'on enregistre un post
*************************************************************************************************/
function msk_save_loves_hates_product_fields($product_id, $post, $update) {
	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;

	if ($post->post_type == 'product') {
		if (isset($_POST['loves'])) {
			$loves = (int)$_POST['loves'];
			update_post_meta($product_id, 'loves', $loves);
		}

		if (isset($_POST['hates'])) {
			$hates = (int)$_POST['hates'];
			update_post_meta($product_id, 'hates', $hates);
		}
	}
}
add_action('save_post', 'msk_save_loves_hates_product_fields', 10, 3);
Nos champs meta produit WooCommerce sont désormais enregistrés dans la base SQL de WordPress
Le SQL des metas du post produit est maintenant à jour

Voila ! Vous pouvez maintenant modifier la valeur des nouveaux champs fraîchement ajoutés et après enregistrement du produit, les nouvelles valeurs seront cette fois correctement enregistrées.

Relier le front-end au back-end

Maintenant que notre back-office dispose de la structure nécessaire pour accueillir de nouvelles données produits, vous pouvez en faire ce que vous voulez sur le front-office de votre boutique.

Petit rappel du template WooCommerce love-product.php défini en première partie de tutoriel :

<?php
/**
 * "I absolutely love this product" tab
 * yourtheme/woocommerce/single-product/tabs/love-product.php
 * @author        Mosaika
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

global $product;

$loves = (get_post_meta($product->id, 'loves', true) != '') ? get_post_meta($product->id, 'loves', true) : 0;
$hates = (get_post_meta($product->id, 'hates', true) != '') ? get_post_meta($product->id, 'hates', true) : 0;

$nonce = wp_create_nonce('love_product'); ?>

<table class="popularity">
	<thead>
		<tr>
			<th><?php _e('Loves', 'msk'); ?></th>
			<th><?php _e('Hates', 'msk'); ?></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td class="loves-number">
				<h3><?php echo $loves; ?></h3>
				<a href="#" class="button alt product-love-hate" data-action="love_product" data-nonce="<?php esc_attr_e($nonce); ?>" data-product-id="<?php esc_attr_e($product->id); ?>">
					<i class="genericon genericon-digg love"></i>
					<span><?php _e('I love this product', 'msk'); ?></span>
				</a>
			</td>
			
			<td class="hates-number">
				<h3><?php echo $hates; ?></h3>
				<a href="#" class="button alt product-love-hate" data-action="hate_product" data-nonce="<?php esc_attr_e($nonce); ?>" data-product-id="<?php esc_attr_e($product->id); ?>">
					<i class="genericon genericon-digg hate"></i>
					<span><?php _e('I hate this product', 'msk'); ?></span>
				</a>
			</td>
		</tr>
	</tbody>
</table>

Comme vous le voyez en ligne 14 et 15, il suffit d’utiliser la fonction get_post_meta() afin de récupérer les valeurs de nos nouveaux champs.

Si vous avez du mal à comprendre la logique de champs meta, ou souhaitez apprendre à afficher leurs valeurs dans votre propre thème WordPress, découvrez notre guide gratuit Types de contenu et champs WordPress.

Mettre à jour les valeurs des champs meta en Ajax

Et pour terminer la logique de nos boutons, je vous laisse analyser le thème mosaikafifteen créé. L’augmentation du nombre de J’aime et de Je déteste se fait grâce à deux fichiers/codes complémentaires :

  1. le fichier js/wc.js envoie une requête Ajax à WordPress en lui indiquant
    1. l’action à faire (love ou hate)
    2. l’ID du produit que le visiteur aime ou déteste (product_id)
    3. et une chaine de sécurité nonce
  2. et c’est la fonction msk_ajax_love_or_hate_product() du fichier functions.php qui s’occupe d’intercepter les requêtes envoyées par le Javascript lorsque l’on clic sur un bouton. En fonction de l’action, le code met à jour la valeur meta du J’aime ou du Je déteste du produit et lui ajoute 1.
    En retour, WordPress renvoie une réponse Ajax avec WP_Ajax_Response en transmettant la nouvelle valeur de loves ou hates. Le fichier js/wc.js intercepte cette réponse et met à jour le titre afin d’afficher le nouveau nombre correctement.

Bien évidemment, un même utilisateur peut pour l’instant cliquer indéfiniment sur les boutons pour augmenter les valeurs, mais le but de ces tutoriels étant tout autre, nous ne nous sommes pas attardés sur ce point.

Conclusion

J’espère que ce duo de tutoriels orientés développement avancé WooCommerce aura pu vous permettre d’y voir plus clair sur la personnalisation du front-office de vos pages produits, et sur la création de nouvelles données dans le back-office d’un produit.

En résumé, nous avons :

  1. créé un onglet sur la page produit
  2. rempli cet onglet avec des données personnalisées
  3. créé des champs meta pour enregistrer des données spécifiques sur les produits WooCommerce
  4. et relié le front-end à ces nouveaux champs meta

Avec cette logique bien en main, les possibilités sont très vastes. Vous êtes désormais en mesure d’enregistrer des nouvelles données très spécifiques à vos produits et afficher leurs valeurs dans votre thème WooCommerce.

Si vous avez des utilisations originales de ces fonctions, faites-nous en part dans les commentaires ci-dessous ! Et si vous appréciez nos articles WordPress et WooCommerce, inscrivez-vous à la newsletter pour recevoir nos futures publications.


Vous avez aimé cet article ?

Partagez-le sur vos réseaux sociaux en guise de remerciement :)


13 commentaires

Tutoriel constructif, cependant le fait que l utilisateur puisse cliquer indéfiniment sur les boutons rend à mon goût tout cela dommage..
Pourquoi ne pas définir un compteur en fonction de l’utilisateur pour qu’il ne puisse pas cliquer plusieurs fois et que cela n’influence pas l’incrémentation au delà de ‘1’.
L’article serait parfait si il y avait cela en complément!

Bonjour Thibault,

Oui je pense que c’est possible, il faudrait stocker dans la BDD (dans une option avec update_option par exemple) la valeur de ce stock unique.
Ensuite il faudrait augmenter/réduire cette valeur à chaque commande (avec des actions WC).
Et faire en sorte que le stock d’un produit soit cette valeur et non le « vrai stock natif » (je pense que ces valeurs doivent être filtrées dans WC).

Bon courage 🙂

bonsoir merci pour ce tutoriel… j’arrive pas à télécharger les fichiers js le lien ne fonctionne pas -_-

Bonjour Pierre, est ce que ce tuto peut-être « détourné » pour faire de commandes de produits avec des champs variables par commande coté utilisateur. Ou faut-il mieux utiliser un plugin spécifique pour personnaliser les produits ?

Bonjour,

C’est possible de le faire « manuellement » sans plugin, mais la technique et le code derrière tout ça sont différents de ce tutoriel.

Bonjour,
Est-ce que ce tuto peut m’aider à ajouter le champ brand ? Est-ce bien ce tuto que je dois suivre car ce champ est déclaré manquant sur la GSC.

Merci d’avance pour votre retour

Bonjour Pierre, merci pour ce tuto très bien construit. Je voudrai savoir s’il est possible d’utiliser ce code pour générer des champs de type texte et champs de type police d’écriture. L’objectif étant de générer un aperçu du texte inscrit avec la police sélectionnée ?

Bonjour,

merci pour ce tuto, il est super clair.

Cependant je n’arrive pas à rentrer du texte dans mon champs, il me retourne sans cesse 0 comme si il n’acceptait que des décimales.

J’ai pourtant changer

‘data_type’ => ‘decimal’,
en
‘type’ => ‘text’,

je ne comprend pas.. Merci de votre retour

Bonjour Santelli,

Il faut enlever (int) qui force l’enregistrement de nombres entier.

Par exemple :
$loves = (int)$_POST[‘loves’]; devient $loves = $_POST[‘loves’];

Laisser un commentaire