Correctif Divi : récupération des « alt text » en bibliothèque

20 Nov 2017

 

EDIT 21/04/2018 : Voir Divi Alt Text 4.0, suite à mise à jour Divi 3.1.

 

EDIT 08/02/2018 : Problème du guid résolu !
Utilisation d’une fonction native de WordPress pour récupérer le texte alternatif 🙂
Nouveau patch 2.0 à télécharger.
Elegant Themes n’a vraiment aucune excuse…
En cherchant dans WordPress comment étaient récupérés les textes alternatifs, j’ai trouvé une fonction propre toute prête à l’emploi !
Le plus drôle, c’est qu’au début j’ai été voir dans d’autres thèmes pour voir comment ils géraient l’affaire. Avada a recodé une fonction propre qui ressemble pas mal à celle de WordPress, et Betheme a carrément utilisé le guid !

 

EDIT 07/02/2018 : La même chose en version plugin !

 

Salut tout le monde,

Ça fait maintenant plusieurs mois que je peste contre Divi à cause de son acharnement à ne pas utiliser les alt text présents en bibliothèque pour les images insérées dans les modules Image, Blurb et Gallery. En effet, Divi ignore purement et simplement cet attribut pour ces trois modules quand même relativement dédiés à l’image !

Une étrange philosophie chez Elegant Themes…

Pour les deux premiers, il faut renseigner le alt text à la main dans le module, donc si on a par exemple importé des images et consciencieusement rempli leur alt text dans la bibliothèque, il faut de toute façon tout refaire dans les modules ! Pour les galeries, c’est pire, Divi cherche cette fois dans la bibliothèque, mais il utilise l’attribut titre, et il est impossible de spécifier les alt text manuellement !

Bref, un comportement complètement anti-ergonomique et incohérent… Quand on sait l’importance de l’attribut pour l’accessibilité d’un site – il est utilisé par les lecteurs d’écran pour les mal/non-voyants – et le référencement, on peut être surpris par Elegant Themes qui rechigne, sans explication (du moins je n’ai rien trouvé), à corriger ce problème. Accessoirement, le staff du support sur leur forum n’a pas l’air très au point sur le sujet, certains expliquant que la modif est prévue, sans donner de date, et d’autres conseillant de la proposer dans la boîte à idées… euh…

Le comble, c’est que la modif du code leur prendrait moins de 5 minutes…

Le patch

Voici donc un petit patch à intégrer dans un thème enfant, forçant les modules Image, Blurb et Gallery à utiliser l’attribut s’il est présent en bibliothèque. Pour assurer la compatibilité ascendante sur les installations existantes, les deux modules à image unique utilisent tout de même l’attribut spécifié dans le module en priorité, et la galerie utilise le titre si le alt text n’est pas renseigné.

EDIT 08/02/2018 : Patch 2.0

Disclaimer : Ce patch a été créé pour Divi 3.0.100.

 

Télécharger le patch 2.0

 

Remarque : Si vous n’avez pas encore de thème enfant, il faut en créer un en suivant les recommandations du Codex WordPress pour les thèmes enfants.

Installation

  1. Copiez les trois fichiers « module » PHP dans le dossier de votre thème enfant.
  2. Ajoutez le contenu de add-to-functions.php à la fin de votre functions.php

Explications

Initialisation du thème enfant

Dans le fichier functions.php, on ajoute le code ci-dessous.

EDIT 08/02/2018

Le premier bloc ajoute une fonction « outil » permettant de trouver l’identifiant du post WordPress associé à une image (l’attachment) en recherchant son chemin dans la base de données (on utilise une requête SQL pour rechercher la chaîne dans le champs guid des posts). Cet ID sera utilisé dans les modules Image et Blurb. Merci à Alexandru Juc du support Divi qui a fourni le code et m’a inspiré pour ce patch !

Pas besoin de passer par le guid car il y a une fonction native dans WordPress qui permet de récupérer le post ID d’un « attachment » à partir de son URL : attachment_url_to_postid()

Le second bloc code va lire les trois fichiers PHP ci-après afin de redéfinir les trois méthodes (dans les langages « orientés objet », une « méthode » est une fonction encapsulée dans une classe) qui construisent les balises HTML des images. Je me suis inspiré de ce tutoriel pour remplacer les modules Divi : je remplace chaque module en effaçant d’abord l’ancienne version (sinon elle est exécutée aussi) et en rajoutant la nouvelle, avec juste la méthode voulue redéfinie.

function get_attachment_id_from_src ($image_src) {
 global $wpdb;
 $query = "SELECT ID FROM {$wpdb->posts} WHERE guid='$image_src'";
 $id = $wpdb->get_var($query);
 return $id;
}

function divi_child_theme_setup() {
 if ( ! class_exists('ET_Builder_Module') ) {
 return;}
 get_template_part( 'Image' );
 $image = new Custom_ET_Builder_Module_Image();
 remove_shortcode( 'et_pb_image' );
 add_shortcode( 'et_pb_image', array($image, '_shortcode_callback') );
 get_template_part( 'Blurb' );
 $blurb = new Custom_ET_Builder_Module_Blurb();
 remove_shortcode( 'et_pb_blurb' );
 add_shortcode( 'et_pb_blurb', array($blurb, '_shortcode_callback') );
 get_template_part( 'Gallery' );
 $gallery = new Custom_ET_Builder_Module_Gallery();
 remove_shortcode( 'et_pb_gallery' );
 add_shortcode( 'et_pb_gallery', array($gallery, '_shortcode_callback') );
}
add_action( 'wp', 'divi_child_theme_setup', 9999 );

Module Image

Dans le fichier Image.php, au lieu de redéfinir le module Image en entier comme dans le tutoriel, j’ai déclaré une classe qui « étend » (qui hérite de) la classe associée au module, dans laquelle je ne redéfinis que la méthode qui nous intéresse, à savoir shortcode_callback(). Cela permet de réduire au minimum le code de substitution dans le fichier, et ainsi de réduire les risques d’être impacté par une mise à jour future de Divi.

Dans la méthode, j’ai ajouté le code suivant (inspiré de la solution d’Alexandru Juc) avant la construction de la balise <img>. Si l’attribut alt text n’est pas renseigné dans le module, on le récupère dans l’attachment correspondant à l’image. S’il n’est toujours pas défini, on prend le titre (c’est toujours mieux que rien).

<?php
class custom_ET_Builder_Module_Image extends ET_Builder_Module_Image {
 function shortcode_callback( $atts, $content = null, $function_name ) {

...

if ( '' === $alt ) {
 $imgID = get_attachment_id_from_src($src);
 $imgID = attachment_url_to_postid($src); 
 $alt = get_post_meta($imgID, '_wp_attachment_image_alt', true);
 if ( '' === $alt )
  $alt = get_the_title($imgID);
}

...

Module Blurb

Dans Blurb.php, même combat pour le module Blurb.

<?php
class Custom_ET_Builder_Module_Blurb extends ET_Builder_Module_Blurb {
 function shortcode_callback( $atts, $content = null, $function_name ) {

...
if ( '' === $alt ) {
 $imgID = get_attachment_id_from_src($image);
 $imgID = attachment_url_to_postid($image); 
 $alt = get_post_meta($imgID, '_wp_attachment_image_alt', true);
 if ( '' === $alt )
  $alt = get_the_title($imgID);
}

...

Module Gallery

Enfin, dans Gallery.php, toujours le même principe, cette fois pour chaque image de la galerie, mais il a fallu aussi modifier les arguments de l’appel à sprintf(), car il en manquait un, le titre étant utilisé à la place du alt text.

<?php
class custom_ET_Builder_Module_Gallery extends ET_Builder_Module_Gallery {
 function shortcode_callback( $atts, $content = null, $function_name ) {

...
$alt = get_post_meta($attachment->ID, '_wp_attachment_image_alt', true);
if ( '' === $alt )
 $alt = $attachment->post_title;
$image_output = sprintf(
 '<a href="%1$s" title="%2$s">
 <img src="%3$s" alt="%4$s" />
 <span class="et_overlay%5$s"%6$s></span>
 </a>',
 esc_url( $attachment->image_src_full[0] ),
 esc_attr( $attachment->post_title ),
 esc_url( $attachment->image_src_thumb[0] ),
 esc_attr( $alt ),
 ( '' !== $hover_icon ? ' et_pb_inline_icon' : '' ),
 $data_icon
);

...

Edit 08/02/2018

Addendum post patch 1.0

Attention au guid des images en bibliothèque

Un petit addendum pour éviter à certains de devenir fou comme moi.

J’ai passé quelques heures à m’arracher les cheveux car je n’arrivais pas à récupérer l’identifiant des attachments associés aux images, alors que tout semblait correct…

Il s’agissait en fait d’une différence de chemin dans le champs guid des posts des images : ils commençaient tous par « http:// » en base de données, alors que partout sur le site (dans les modules en particulier), j’avais remplacé le préfixe des chemins par « https:// » suite au passage de mon site en HTTPS. En effet, le guid est un identifiant unique positionné par WordPress avec le chemin d’origine du post, mais il n’est plus mis à jour par la suite, donc il ne reflète pas forcément l’URL exacte du fichier image.

Avec l’aide de l’excellent plugin Migrate DB, j’ai donc dû modifier tous ces « http » restant en « https »… Merci Migrate DB. Cette extension gratuite est trop pratique pour taper en base de données sans intervenir directement en SQL (et en « root »).

Notez bien que le problème serait le même suite à un changement de nom de domaine ou à un déplacement de fichiers ou répertoires dans l’arborescence des uploads de WordPress.

Attention au guid… le retour !

Maintenant, un autre problème survient : la modification des guid rentre en conflit avec la gestion du flux RSS.

Diantre… Bon personnellement j’ai lu ça trop tard, et comme je n’ai pas trop d’articles, j’ai considéré que ce n’était pas très grave, mais sur d’autres sites, ça pourrait être ennuyeux. A bon entendeur…

Pour info, il y a des solutions plus complexes qui permettent de contourner le problème, mais elles sont aussi plus lourdes, ou posent des problèmes de performance pour des sites volumineux. Vous pouvez consulter à ce sujet ces trois intéressants fils de discussion :

Conclusion

Voilà, les images de votre site sont maintenant en béton, avec dans le pire des cas le titre comme alt text, et dans le meilleur celui que vous avez défini en bibliothèque. Comme vous le voyez, rien de bien sorcier… Qu’attend donc ET pour l’intégrer à Divi ? Si vous avez eu vent d’une contre-indication ou d’une quelconque justification de leur part, je suis preneur !

Bien sûr, malgré l’utilisation d’un thème enfant, il faudra quand même vérifier si les mises à jour de Divi touchent aux trois méthodes modifiées, et le cas échéant, récupérer les versions mises à jour dans l’arborescence Divi, les recopier dans les trois fichiers du thème enfant, et reporter dedans les modifications de ce patch (le code ci-dessus). A moins que… ce soit justement cette modif qui soit intégrée. Allez on leur met la pression !