Comment ajouter l’Ă©diteur de bloc de WordPress dans les fiches produits de WooCommerce ?

L’autre matin, je voulais une mise en page un peu particulière pour prĂ©senter le dĂ©roulĂ© d’une formation qui est un produit de WooCommerce. Qu’Ă  cela ne tienne je vais crĂ©er un modèle de page personnalisĂ© pour les types de contenu « Product ».

Hey mais attends, si c’est un Custom Post Type, il devrait y avoir Gutenberg, l’Ă©diteur de blocs de WordPress Ă  dispo non ?

En rĂ©sumĂ© voici comment on va s’y prendre :

WooCommerce désactive Gutenberg par défaut

Puis je me suis mis à rechercher « gutenberg » sur le repo de WooCommerce pour y trouver un commit intéressant :

Github.com Woocommerce Woocommerce Search Q=gutenberg&type=commits (1)

« Disable Gutenberg for products », ça me paraĂ®t assez explicite. Je me rend compte que l’extension utilise un filtre pour dĂ©sactiver Gutenberg :

add_filter( 'gutenberg_can_edit_post_type', array( __CLASS__, 'gutenberg_can_edit_post_type' ), 10, 2 );

/**
 * Disable Gutenberg for products.
 *
 * @param bool   $can_edit Whether the post type can be edited or not.
 * @param string $post_type The post type being checked.
 * @return bool
 */
public static function gutenberg_can_edit_post_type( $can_edit, $post_type ) {
    return 'product' === $post_type ? false : $can_edit;
}

Pour faire simple, WooCommerce vérifie si mon $post_type est de type product alors le plugin return false.

Si on va sur la branche master du repo on voit cette logiqe appliquée sur 2 hooks différents :

En clair, WooCommerce ne veut pas de Gutenberg dans ses fiches produits.

Mais si ce n’est qu’une question de hooks, 🤔 je dois pouvoir rĂ©activer l’Ă©diteur de blocs !

Activer Gutenberg pour les produits grâce aux hooks

Je vais tout simplement coder l’inverse de ce que WooCommerce me prĂ©sente.

Commençons par créer une extension :

Dans le dossier /wp-content/plugins je crĂ©Ă© un nouveau dossier que j’appelle gutenberg-for-woocommerce. Pour respecter les bonnes pratiques de WordPress, je crĂ©er un fichier gutenberg-for-woocommerce.php Ă  l’intĂ©rieur de ce nouveau dossier.

/**
 * Enable Gutenberg for products.
 *
 * @see https://github.com/woocommerce/woocommerce/commit/0599c06b20a6fd38547588d25f2e3c43a6d4503a#
 */
function woocommerce_for_gutenberg_enable_block_editor_for_products() {
	remove_filter( 'gutenberg_can_edit_post_type', array( WC_Post_Types::class, 'gutenberg_can_edit_post_type' ), 10, 2 );
	remove_filter( 'use_block_editor_for_post_type', array( WC_Post_Types::class, 'gutenberg_can_edit_post_type' ), 10, 2 );
}
add_action( 'plugins_loaded', 'woocommerce_for_gutenberg_enable_block_editor_for_products' );

En bref, lorsque les extensions de WordPress sont chargĂ©es, je viens lancer la fonction woocommerce_for_gutenberg_enable_block_editor_for_products qui s’occupe de supprimer les filtres de WooCommerce.

Libre Ă  vous d’adapter le code selon que vous ĂŞtes plus Ă  l’aise en Programmation OrientĂ©e Objet qu’en procĂ©dural. J’essaie de rester simple dans la dĂ©monstration pour une meilleure comprĂ©hension.

Modifier le template d’une fiche produit WooCommerce

C’est bien beau d’avoir activer Gutenberg pour Ă©diter le contenu de nos fiches produits mais si l’affichage cotĂ© front ne suit pas je ne profiterais pas de toute la puissance qu’offrent les blocs.

Je vais donc modifier le template de ma fiche produit. D’après la hiĂ©rarchie des templates de WordPress je dois m’attaquer au fichier single-product.php.

Rendez-vous dans /wp-content/plugins/woocommerce/templates/single-product.php pour se rendre compte que WooCommerce gère son affichage avec des actions (encore une fois des hooks !).

do_action( 'woocommerce_before_main_content' );

while ( have_posts() ) { 
  the_post();
  wc_get_template_part( 'content', 'single-product' );
}

do_action( 'woocommerce_after_main_content' );
do_action( 'woocommerce_sidebar' );

J’ai tej les commentaires pour plus de lisibilitĂ© mais ils donnent tous les dĂ©tails sur ce qui est implĂ©mentĂ© sur chaque hook.

Comme la finesse et moi c’est discutable, je pars du principe que tout ce que je peux dĂ©sactiver je le vire Ă  commencer par les <div> que WooCommerce gĂ©nère dont j’ai pas besoin.

function gutenberg_for_woocommerce_remove_all_single_template_actions() {
  remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10 );
  remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10 );
}
add_action( 'after_setup_theme', 'gutenberg_for_woocommerce_remove_all_single_template_actions' );

DĂ©sactiver le fil d’Ariane de WooCommerce

Viens le tour du fil d’ariane que je pourrais ajouter plus tard sous forme de bloc Ă  l’endroit oĂą je veux.

DĂ©sactivons-le pour le moment :

function gutenberg_for_woocommerce_remove_all_single_template_actions() {
  	remove_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20 ); // DĂ©sactiver le fil d'ariane de WooCommerce.

add_action( 'after_setup_theme', 'gutenberg_for_woocommerce_remove_all_single_template_actions' );

Pour la suite nous devons examiner de plus prêt la Boucle de WooCommerce pour voir ce qui se cache derrière wc_get_template_part( 'content', 'single-product' );

DĂ©sactiver le titre de la fiche produit

DĂ©sactivons-le pour le moment :

function gutenberg_for_woocommerce_remove_all_single_template_actions() {
  	

add_action( 'after_setup_theme', 'gutenberg_for_woocommerce_remove_all_single_template_actions' );
function gutenberg_for_woocommerce_remove_all_single_template_actions() {
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10 ); // Supprimer <div id="primary" class="content-area"><main id="main" class="site-main" role="main">
	remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10 ); // Supprimer </div>
	remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_sale_flash', 10 );
	remove_action( 'woocommerce_before_single_product_summary', 'woocommerce_show_product_images', 20 );
	remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_title', 5 );
	remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_rating', 10 );
	remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
	remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_excerpt', 20 );
	remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
	remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_meta', 40 );
	remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_sharing', 50 );
	remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_product_data_tabs', 10 );
	remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_upsell_display', 15 );
	remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20 );
}
add_action( 'after_setup_theme', 'gutenberg_for_woocommerce_remove_all_single_template_actions' );

En résumé pour tout désactiver sur la fiche produit généré par WooCommerce

Afficher le contenu de l’Ă©diteur de bloc

Cool, on a fait un sacrĂ© mĂ©nage, mais… je n’ai pas le contenu de ma page qui s’affiche pour autant.

Comment créer des blocs pour afficher les informations du produit ?

Comme le template utilisait des hooks, je me suis fait une reflexion aussi bĂŞte que simple : pourquoi ne pas rĂ©utiliser la mĂŞme mĂ©thode qui Ă©tait dĂ©jĂ  branchĂ© sur une action du template auparavant. Elles gĂ©raient dĂ©jĂ  l’affichage en front, je ne vais pas rĂ©inventer la roue.

Par exemple, j’utiliserais la fonction woocommerce_template_single_price pour afficher le prix, ou woocommerce_template_single_add_to_cart pour afficher le bouton d’ajout au panier.

Exemple de bloc Gutenberg pour afficher le prix du produit

Histoire d’avancer sur notre plugin, je vous propose de crĂ©er un 1er bloc pour afficher le prix de notre produit.