Nous maintenons depuis plusieurs années un plugin qui propose une dizaine de shortcodes : galerie de témoignages, tableau de tarifs, bandeau d’alerte, liste de logos partenaires. Fonctionnels, mais franchement datés à l’usage : l’utilisateur devait mémoriser une syntaxe entre crochets, sans aperçu, sans autocomplétion, avec un risque d’erreur de frappe qui casse silencieusement l’affichage.
Ce retour d’expérience détaille comment nous avons migré ce plugin vers des blocs Gutenberg, les pièges rencontrés en cours de route, et surtout comment nous avons évité de casser le contenu de nos utilisateurs déjà en production sur des centaines de sites.
Pourquoi ne pas simplement remplacer les shortcodes
La première tentation, en début de projet, a été de supprimer purement et simplement les shortcodes au profit des nouveaux blocs. Mauvaise idée : des milliers d’articles existants contenaient déjà ces shortcodes dans leur contenu, stockés tels quels en base de données. Les supprimer aurait cassé instantanément l’affichage de tout le contenu existant, dès la mise à jour du plugin.
Nous avons donc posé une règle simple dès le départ : les shortcodes restent fonctionnels indéfiniment, et les nouveaux blocs viennent s’ajouter à côté, sans rien retirer. Le plugin add_shortcode() reste appelé exactement comme avant.
Un bloc peut appeler un shortcode existant

Pour aller vite sur les blocs les plus simples, nous avons choisi de ne pas réécrire toute la logique d’affichage. Le bloc se contente de générer les bons attributs via son interface d’édition, puis délègue le rendu final au shortcode existant, dont la fonction PHP est déjà testée depuis des années :
<?php
function wpmoderne_render_tableau_tarifs( $attributes ) {
$shortcode_atts = [
'plan' => $attributes['plan'] ?? 'standard',
'devise' => $attributes['devise'] ?? 'EUR',
];
return do_shortcode(
sprintf(
'[tarifs plan="%s" devise="%s"]',
esc_attr( $shortcode_atts['plan'] ),
esc_attr( $shortcode_atts['devise'] )
)
);
}
Cette approche transitoire nous a permis de livrer une première vague de blocs en quelques semaines, sans risque de régression sur la logique métier déjà éprouvée. Les blocs plus récents, écrits ensuite, ont un rendu propre en render.php, sans passer par do_shortcode().
Le piège de la conversion automatique
Nous avons un temps envisagé de convertir automatiquement les shortcodes existants en blocs, au moment de l’ouverture de l’éditeur, via un filtre sur the_content ou une transformation à l’enregistrement. L’idée était séduisante sur le papier, mais s’est révélée risquée en pratique : certains shortcodes contenaient des paramètres saisis à la main, avec des variations de casse ou d’espacement que notre expression régulière de conversion ne gérait pas toujours correctement.
Nous avons abandonné cette voie automatique au profit d’une cohabitation durable. Un shortcode ancien reste un shortcode ; seuls les nouveaux contenus, créés après la mise à jour, utilisent les blocs. Une documentation a suffi à orienter les utilisateurs les plus actifs vers la nouvelle interface, sans forcer personne.
Adapter l’interface d’édition aux habitudes existantes
Un autre enseignement de cette migration concerne l’expérience d’édition elle-même. Nos utilisateurs connaissaient déjà les paramètres de chaque shortcode : reproduire exactement les mêmes options dans le panneau InspectorControls du bloc, avec les mêmes libellés, a considérablement réduit la courbe d’apprentissage. Un changement de vocabulaire, même mineur, aurait généré des tickets de support inutiles.
- Reprendre les mêmes noms de paramètres entre le shortcode et les attributs du bloc, pour faciliter la compréhension.
- Proposer un aperçu fidèle dans l’éditeur, ce que le shortcode ne permettait jamais.
- Documenter clairement, dans le changelog, que l’ancien shortcode reste utilisable sans limite de durée.
Gérer le contenu déjà présent avec un pattern de transformation
Pour les utilisateurs qui souhaitaient activement migrer leurs anciens contenus, nous avons ajouté une transformation de bloc personnalisée, basée sur transforms.from avec le type shortcode. Concrètement, lorsqu’un shortcode reconnu est collé dans l’éditeur, Gutenberg propose de le convertir automatiquement en bloc équivalent :
transforms: {
from: [
{
type: 'shortcode',
tag: 'tarifs',
attributes: {
plan: {
type: 'string',
shortcode: ( { named: { plan } } ) => plan || 'standard',
},
},
},
],
},
Cette fonctionnalité, purement opt-in, a été très bien accueillie : elle laisse le choix à l’utilisateur, sans jamais modifier de contenu existant sans action explicite de sa part.
En résumé
Migrer un plugin de shortcodes vers des blocs ne signifie pas nécessairement tout réécrire d’un coup. La stratégie la plus sûre reste la cohabitation : garder les shortcodes actifs indéfiniment, faire reposer les premiers blocs sur la logique de rendu déjà éprouvée, puis proposer une transformation optionnelle pour les utilisateurs volontaires. C’est plus lent qu’une bascule totale, mais c’est la seule approche qui ne casse jamais un site en production.