# WP_HTML_Tag_Processor : ajouter un attribut à toutes les images sans regex

> Modifier du HTML stocké en base avec une expression régulière finit toujours par casser une balise imbriquée. La classe WP_HTML_Tag_Processor, native depuis WordPress 6.2, fait le travail proprement.

- Auteur : WordPress Développement
- Publié le : 2023-08-13
- Mis à jour le : 2023-08-13
- Catégorie : Astuces
- URL : https://www.wpmoderne.fr/tips/wp-html-tag-processor-ajouter-attribut-images-sans-regex/

## L’essentiel

- WP_HTML_Tag_Processor est disponible nativement depuis WordPress 6.2
- Elle parcourt le HTML sans jamais le parser en arbre complet
- Elle évite les regex fragiles sur des attributs existants

```
preg_replace( '/<img(.*?)>/i', '<img$1 loading="lazy">', $contenu );
```

Cette ligne fonctionne, jusqu'au jour où une image contient déjà un attribut `alt` avec un chevron mal échappé dans un texte collé depuis Word, ou un attribut `style` contenant un signe supérieur dans un calcul CSS improbable. Les expressions régulières ne comprennent pas le HTML : elles comprennent du texte qui ressemble à du HTML, ce qui n'est pas la même chose.

Pour insérer, modifier ou lire un attribut sur des balises `<img>` présentes dans du contenu déjà enregistré, WordPress propose depuis la version 6.2 une classe cœur pensée exactement pour ce cas d'usage : `WP_HTML_Tag_Processor`. Elle ne construit pas un arbre DOM complet comme le ferait `DOMDocument`, elle avance dans le flux HTML balise par balise, ce qui la rend à la fois rapide et tolérante aux documents partiels.

## Pourquoi les regex échouent sur du HTML

Un attribut peut contenir des guillemets échappés, des espaces multiples, ou être absent alors qu'une regex suppose sa présence. Une balise peut aussi être auto-fermante ou non selon le contexte. Dès que le contenu provient d'un éditeur WYSIWYG, d'un import externe ou d'un collage depuis un traitement de texte, la probabilité qu'une regex censée cibler des balises `img` capture trop ou trop peu de texte augmente fortement.

## Ce que fait réellement WP_HTML_Tag_Processor

La classe expose une méthode `next_tag()` qui avance jusqu'à la balise suivante correspondant à un sélecteur donné, puis des méthodes comme `get_attribute()`, `set_attribute()` ou `remove_attribute()` pour manipuler les attributs de la balise courante. Une fois toutes les modifications faites, `get_updated_html()` retourne le HTML corrigé, sans avoir touché au reste du document.

> L'essentiel à retenir : WP_HTML_Tag_Processor est disponible nativement depuis WordPress 6.2 ; Elle parcourt le HTML sans jamais le parser en arbre complet ; Elle évite les regex fragiles sur des attributs existants

## Ajouter loading="lazy" à toutes les images

Voici un exemple appliqué au contenu d'un article via le filtre `the_content` :

```
add_filter( 'the_content', 'wpm_ajouter_lazy_loading_images' );

function wpm_ajouter_lazy_loading_images( $contenu ) {
    $processor = new WP_HTML_Tag_Processor( $contenu );

    while ( $processor->next_tag( 'img' ) ) {
        if ( ! $processor->get_attribute( 'loading' ) ) {
            $processor->set_attribute( 'loading', 'lazy' );
        }
    }

    return $processor->get_updated_html();
}
```

La condition sur `get_attribute( 'loading' )` évite d'écraser une valeur déjà présente, par exemple `eager` posée volontairement sur l'image visible en premier écran. C'est précisément le genre de nuance qu'une regex gère mal sans multiplier les cas particuliers.

## Ajouter un attribut de données personnalisé

La même mécanique permet d'ajouter un attribut `data-` utilisé par un script de suivi ou une bibliothèque de galerie :

- Repérer les images sans attribut `data-lightbox` déjà présent.
- Leur ajouter un identifiant unique basé sur leur position dans le contenu.
- Laisser les autres balises du document totalement intactes, y compris les commentaires de blocs Gutenberg.

```
$processor = new WP_HTML_Tag_Processor( $contenu );
$compteur  = 0;

while ( $processor->next_tag( 'img' ) ) {
    $compteur++;
    $processor->set_attribute( 'data-lightbox-id', 'img-' . $compteur );
}

return $processor->get_updated_html();
```

### Cibler une classe précise

La méthode `next_tag()` accepte un tableau de critères, par exemple `array( 'tag_name' => 'img', 'class_name' => 'aligncenter' )`, ce qui permet de ne modifier que les images centrées sans avoir à analyser vous-même la chaîne de classes.

> Conseil maison : gardez toujours la classe pour des modifications superficielles — attributs, classes, valeurs. Dès qu'il faut déplacer une balise, en supprimer une entière ou restructurer l'arbre, cette classe atteint ses limites et une autre approche devient nécessaire.

## Les limites à connaître

La classe ne gère pas la modification de structure : impossible d'envelopper une image dans une balise `figure` ou de la déplacer ailleurs dans le document avec cette seule API. Elle ne parse pas non plus le contenu texte entre les balises, seulement les balises elles-mêmes et leurs attributs. Pour des restructurations profondes de blocs imbriqués, il faut se tourner vers l'API des blocs ou une transformation côté éditeur plutôt que vers une modification de la chaîne HTML finale.

## En résumé

Depuis WordPress 6.2, il n'y a plus de raison de manipuler du HTML stocké au moyen d'expressions régulières fragiles quand il s'agit d'ajouter, de lire ou de retirer des attributs. `WP_HTML_Tag_Processor` fait ce travail de façon fiable, sans dépendance externe et sans le coût de performance d'un parseur DOM complet. Le réflexe à adopter : dès qu'une regex commence à contenir plus de deux groupes de capture pour cibler du HTML, c'est le signal qu'il est temps de basculer vers cette classe.
