Chapitre 7.6 — Shortcodes & widgets
⏱️ TL;DR — Un shortcode est une balise
[wpr_livres genre="roman"]insérable dans du contenu, remplacée par du HTML généré par votre PHP (add_shortcode). Un shortcode retourne son HTML (jamais d’echo). Les widgets classiques (zones latérales) existent encore mais cèdent la place aux blocs (Partie 8) dans l’éditeur moderne. À l’ère Gutenberg, préférez souvent un bloc (statique ou dynamique) à un shortcode — mais le shortcode reste utile (compatibilité, insertion rapide, usage dans des textes/e-mails).
🎯 Objectifs
- Créer un shortcode avec attributs, proprement (retour, sécurité).
- Comprendre la place des widgets aujourd’hui.
- Choisir entre shortcode et bloc.
- Éviter les pièges (echo, attributs non assainis).
1. Un shortcode de base
add_action( 'init', function () {
add_shortcode( 'wpr_livres', 'wpr_books_shortcode' );
} );
function wpr_books_shortcode( $atts, $content = '' ) {
// 1) Fusionner attributs fournis + valeurs par défaut
$atts = shortcode_atts( array(
'genre' => '',
'nombre' => 5,
), $atts, 'wpr_livres' );
// 2) Requête (arguments assainis)
$args = array(
'post_type' => 'livre',
'posts_per_page' => absint( $atts['nombre'] ),
);
if ( $atts['genre'] ) {
$args['tax_query'] = array( array(
'taxonomy' => 'genre',
'field' => 'slug',
'terms' => sanitize_title( $atts['genre'] ),
) );
}
$q = new WP_Query( $args );
// 3) Construire le HTML dans une chaîne (buffer) et le RETOURNER
ob_start();
if ( $q->have_posts() ) {
echo '<ul class="wpr-livres">';
while ( $q->have_posts() ) { $q->the_post();
printf(
'<li><a href="%s">%s</a></li>',
esc_url( get_permalink() ),
esc_html( get_the_title() )
);
}
echo '</ul>';
wp_reset_postdata();
}
return ob_get_clean(); // ⚠️ on RETOURNE, on n'echo pas
}⚠️ Piège n°1 —
echodans un shortcode. Un shortcode doit retourner son HTML, pas l’afficher. Si vousechodirectement, le contenu apparaît au mauvais endroit (au tout début de la page, avant le rendu). On bufferise avecob_start()/ob_get_clean()si le HTML est long, et on retourne.
⚠️ Piège n°2 — attributs non assainis. Les attributs viennent du contenu (donc potentiellement d’un utilisateur avec droit d’édition) : assainissez-les (
absint,sanitize_title,sanitize_text_field) avant de les utiliser dans une requête ou de les afficher. Et échappez à la sortie (esc_html,esc_url).
2. Attributs et contenu englobé
shortcode_atts()fusionne les attributs fournis avec des valeurs par défaut (et normalise en minuscules).- Un shortcode englobant reçoit le contenu entre balises :
[wpr_encadre]du texte[/wpr_encadre]→$content= « du texte ». Pensez à traiter$content(souvent viado_shortcode()pour les shortcodes imbriqués, et à l’échapper/wp_ksessi nécessaire).
function wpr_encadre( $atts, $content = '' ) {
return '<div class="wpr-encadre">' . do_shortcode( $content ) . '</div>';
}3. Les widgets aujourd’hui
Historiquement, les widgets remplissaient des zones (sidebars) déclarées par le thème (register_sidebar). Depuis WordPress 5.8, l’écran Apparence → Widgets est lui-même basé sur des blocs : on place des blocs dans les zones de widgets. Les widgets « classiques » (classe WP_Widget) restent supportés pour la compatibilité, mais pour du neuf, on crée un bloc (Partie 8).
💡 Pour un dev React — Le shortcode est un mini-composant serveur inséré par balise textuelle (
[tag attrs]→ HTML), un peu comme un MDX shortcode. Le widget classique est un composant de zone de l’ancien monde. Le bloc (Partie 8) est le composant React moderne, éditable visuellement, qui remplace les deux dans la plupart des cas neufs. Retenez la trajectoire : shortcode/widget = héritage utile ; bloc = présent et futur.
4. Shortcode ou bloc ? (choisir)
| Critère | Shortcode | Bloc (Partie 8) |
|---|---|---|
| Insertion | Balise texte (dans contenu, widgets, e-mails) | Visuel, dans l’éditeur |
| Aperçu | Non (texte brut dans l’éditeur) | Oui (rendu live + réglages) |
| Public | Compatibilité, non-Gutenberg, rapide | Éditeurs modernes, UX riche |
| Dev | Simple (PHP) | React + build (mais plus puissant) |
Recommandation : pour du contenu inséré par un créateur dans l’éditeur moderne → bloc dynamique (Partie 8), souvent adossé au même callback PHP de rendu. Le shortcode reste pertinent pour la compatibilité, une insertion rapide, ou un usage hors éditeur de blocs. Beaucoup de plugins offrent les deux (un bloc et un shortcode partageant la même logique de rendu).
5. Bonnes pratiques
- Enregistrer sur
init. - Retourner (jamais
echo). - Assainir les attributs, échapper les sorties.
- Réinitialiser après une requête secondaire (
wp_reset_postdata). - Nommer/préfixer le shortcode (
wpr_livres) pour éviter les collisions.
✏️ Exercices
- Corrigez le défaut : un shortcode qui fait
echo '<div>…</div>';à la fin. Que se passe-t-il et comment corriger ? - Un attribut
genreest utilisé dans unetax_query. Comment l’assainir ? - Pour un nouvel élément inséré visuellement par un créateur dans l’éditeur, shortcode ou bloc ? Pourquoi ?
✅ Solution
- Le contenu s’affiche au mauvais endroit (au début de la page) car un shortcode doit retourner, pas afficher. Correction : bufferiser avec
ob_start()/ob_get_clean()etreturnle HTML. - Avec
sanitize_title()(le genre est comparé à un slug de terme) :sanitize_title( $atts['genre'] )— jamais utiliser la valeur brute dans la requête. - Un bloc (Partie 8) : aperçu live dans l’éditeur, réglages visuels, meilleure UX pour un créateur. Le shortcode reste utile pour la compatibilité ou l’insertion hors éditeur de blocs.
🧠 Quiz de révision
1. Un shortcode doit-il echo ou return son HTML ?
Il doit retourner (return) son HTML, jamais l’echo (sinon affichage au mauvais endroit).
2. À quoi sert shortcode_atts() ?
À fusionner les attributs fournis avec des valeurs par défaut (et à les normaliser).
3. Les widgets classiques sont-ils obsolètes ?
Toujours supportés (compatibilité), mais pour du neuf on crée un bloc ; les zones de widgets acceptent désormais des blocs.
4. Comment sécuriser un attribut de shortcode ?
L’assainir selon son type (absint, sanitize_title, sanitize_text_field) avant usage, et échapper à la sortie.
5. Quel avantage majeur d’un bloc sur un shortcode ?
L’aperçu live et les réglages visuels dans l’éditeur (UX pour le créateur).
Chapitre suivant : Sécurité : nonces, sanitize, escape, capabilities.