Skip to content
⚡ Comment ajouter votre propre shortcode dans WordPress : exemples et code

⚡ Comment ajouter votre propre shortcode dans WordPress : exemples et code

Vous devez afficher la date de dernière mise à jour d’un article dans le pied de page de chaque contenu. Ou insérer un formulaire d’abonnement exactement au milieu du texte, sans jongler avec un éditeur de code et des templates. Dans WordPress, les shortcodes sont l’outil prévu pour cela.

Un shortcode est une balise courte entre crochets: [myshortcode]. WordPress la repère dans le contenu et la remplace par le résultat d’une fonction PHP. Vous utilisez des shortcodes standards comme [gallery] et [embed] en permanence sans même y penser. Mais votre propre shortcode est un levier: vous écrivez la logique une fois, et le rédacteur l’insère n’importe où en trois clics.

En 10 minutes, vous allez créer votre premier shortcode fonctionnel: d’une fonction vide à une balise avec attributs et contenu englobé. Le code est réel, il tourne sur n’importe quel WordPress moderne et a été testé sur un site de staging.

💡 Aperçu rapide:

  • La fonction add_shortcode: ce qu’elle accepte et comment elle fonctionne en interne
  • Un shortcode basique [current_year], l’année en cours sous forme de texte
  • Un shortcode avec attributs [cta text="Скачать"], un bouton personnalisé
  • Un shortcode avec contenu englobé [notice]Текст[/notice], un bloc stylisé
  • Ajout via un plugin ou functions.php: avantages et inconvénients de chaque approche
  • Erreurs fréquentes: echo au lieu de return, conflits de noms, attribut vide en PHP 8+

Ce que add_shortcode permet de faire et comment cela fonctionne

La fonction add_shortcode est le seul moyen standard d’enregistrer un nouveau shortcode dans WordPress. Elle accepte deux paramètres:

  • $tag (chaîne), le nom du shortcode que vous écrirez entre crochets. Uniquement des lettres, des chiffres et des tirets bas. Les espaces et les caractères spéciaux & / < > [ ] = sont interdits; WordPress refusera silencieusement d’enregistrer une telle balise.
  • $callback (callable), le nom de la fonction PHP qui sera déclenchée lorsque le shortcode est trouvé. Cette fonction génère le HTML que le visiteur verra.

Le code source de la fonction, cinq lignes de logique et deux vérifications de cohérence (listing complet sur developer.wordpress.org):

1function add_shortcode( $tag, $callback ) {
2 global $shortcode_tags;
3
4 if ( '' === trim( $tag ) ) {
5 _doing_it_wrong(
6 __FUNCTION__,
7 __( 'Invalid shortcode name: Empty name given.' ),
8 '4.4.0'
9 );
10 return;
11 }
12
13 if ( 0 !== preg_match( '@[<>&/\[\]\x00-\x20=]@', $tag ) ) {
14 _doing_it_wrong(
15 __FUNCTION__,
16 sprintf(
17 /* translators: 1: Shortcode name, 2: Space-separated list of reserved characters. */
18 __( 'Invalid shortcode name: %1$s. Do not use spaces or reserved characters: %2$s' ),
19 $tag,
20 '& / < > [ ] ='
21 ),
22 '4.4.0'
23 );
24 return;
25 }
26
27 $shortcode_tags[ $tag ] = $callback;
28}

Le point clé: $shortcode_tags, un tableau global. WordPress y stocke tous les shortcodes enregistrés. Lors du rendu du contenu, le cœur parcourt ce tableau et appelle la fonction associée pour chaque balise trouvée. Deux conséquences en découlent:

  • *Enregistrez-vous sur le hook init.* Si vous appelez add_shortcode directement dans un fichier de plugin, elle peut s’exécuter avant que WordPress ne soit complètement initialisé. La bonne pratique consiste à l’encapsuler dans un hook:
1add_action( 'init', 'my_register_shortcodes' );
2
3function my_register_shortcodes() {
4 add_shortcode( 'mytag', 'my_shortcode_callback' );
5}
  • Un préfixe est obligatoire. Le tableau global est partagé par tous les plugins et le thème. Si vous nommez un shortcode [button], votre [button] écrase silencieusement le même shortcode provenant d’un plugin de formulaires. Un préfixe comme myplugin_ ou une abréviation unique résout le problème. Dans les exemples ci-dessous, j’utilise le préfixe mysite_; dans un projet réel, remplacez-le par le vôtre.

Étape 1: un shortcode simple sans paramètres

Le chemin le plus court vers un shortcode fonctionnel, trois lignes dans le functions.php de votre thème enfant (ou dans le plugin Code Snippets, ce qui est plus sûr et ne sera pas perdu lors d’une mise à jour du thème).

Ajoutez ce code et enregistrez:

1add_shortcode( 'mysite_current_year', 'mysite_display_current_year' );
2
3function mysite_display_current_year() {
4 return date( 'Y' );
5}

Écrivez maintenant [mysite_current_year] dans n’importe quel article ou page. Côté front-end, l’année en cours apparaîtra à la place du shortcode: «2026».

Ce qui se passe ici. La fonction mysite_display_current_year ne prend aucun argument, appelle la fonction PHP date('Y') et retourne une chaîne de quatre chiffres. WordPress insère cette chaîne exactement à l’endroit où le shortcode a été placé. Aucune magie.

Où appliquer cela en pratique: l’année dans le pied de page (© [mysite_current_year]), l’ancienneté du projet dans un texte («en activité depuis [mysite_current_year]»), la mise à jour automatique des dates sur les pages de conformité légale.

Étape 2: un shortcode avec attributs

Un shortcode sans paramètre est utile, mais la vraie flexibilité commence avec les attributs. L’exemple classique: un bouton dont le texte et le lien sont personnalisables.

1add_shortcode( 'mysite_cta', 'mysite_cta_button' );
2
3function mysite_cta_button( $atts ) {
4 $atts = shortcode_atts(
5 array(
6 'text' => 'Learn more',
7 'url' => '#',
8 ),
9 $atts,
10 'mysite_cta'
11 );
12
13 return sprintf(
14 '<a href="%s" class="mysite-cta-button">%s</a>',
15 esc_url( $atts['url'] ),
16 esc_html( $atts['text'] )
17 );
18}

Dans l’éditeur, utilisez-le ainsi:

1[mysite_cta text="Download plugin" url="https://example.com/myplugin/"]

La fonction shortcode_atts fait trois choses à la fois: elle fusionne les attributs saisis par l’utilisateur avec les valeurs par défaut, ne conserve que les clés connues et normalise une chaîne vide en tableau (sans cela, appeler [mysite_cta] sans attribut sous PHP 8+ provoquerait une TypeError, car le premier paramètre de la fonction de rappel recevrait une chaîne vide au lieu d’un tableau).

*Pourquoi esc_url et esc_html.* Un shortcode est inséré par un éditeur, aujourd’hui c’est vous, demain ce sera un responsable de contenu sans accès au code. L’échappement de la sortie protège contre un XSS accidentel si un chevron ou une balise se retrouve dans l’attribut text.

Étape 3: un shortcode avec contenu englobé

Certains shortcodes enveloppent un fragment de texte: [mysite_notice]Важное сообщение[/mysite_notice]. Le contenu englobé arrive dans la fonction de rappel comme second paramètre, $content. Un scénario typique: un bloc d’avertissement mis en forme.

1add_shortcode( 'mysite_notice', 'mysite_notice_box' );
2
3function mysite_notice_box( $atts, $content = null ) {
4 $atts = shortcode_atts(
5 array(
6 'type' => 'info',
7 ),
8 $atts,
9 'mysite_notice'
10 );
11
12 $class = 'notice-' . esc_attr( $atts['type'] );
13
14 return sprintf(
15 '<div class="mysite-notice %s"><p>%s</p></div>',
16 $class,
17 do_shortcode( $content )
18 );
19}

Remarquez le do_shortcode( $content ). Si l’éditeur a inséré un autre shortcode à l’intérieur du vôtre (par exemple [mysite_current_year]), cet appel l’exécutera également. Sans do_shortcode, les shortcodes imbriqués s’afficheront sous forme de texte entre crochets, [mysite_current_year] brut au lieu de «2026».

Le CSS du bloc, minimal, pour démarrer:

1.mysite-notice {
2 border-left: 4px solid #2271b1;
3 background: #f0f6fc;
4 padding: 1em 1.2em;
5 margin: 1.5em 0;
6 border-radius: 4px;
7}
8.mysite-notice.notice-warning {
9 border-left-color: #dba617;
10 background: #fcf9e8;
11}

Ajoutez ces styles dans le style.css de votre thème enfant ou via Apparence → Personnaliser → CSS additionnel.

Étape 4: un shortcode dans une extension (approche objet)

Quand vous dépassez trois shortcodes, functions.php se transforme en fourre-tout. Il est temps de déplacer la logique dans une extension séparée, et idéalement dans une classe. Voici un squelette de mini-extension avec un shortcode:

1<?php
2/**
3 * Plugin Name: MySite Shortcodes
4 * Description: Custom shortcodes for the site.
5 * Version: 1.0.0
6 * Requires PHP: 7.4
7 */
8
9defined( 'ABSPATH' ) || exit;
10
11class MySite_Shortcodes {
12
13 public static function init() {
14 add_action( 'init', array( __CLASS__, 'register' ) );
15 }
16
17 public static function register() {
18 add_shortcode( 'mysite_email', array( __CLASS__, 'email_obfuscated' ) );
19 }
20
21 public static function email_obfuscated( $atts ) {
22 $atts = shortcode_atts(
23 array( 'address' => '' ),
24 $atts,
25 'mysite_email'
26 );
27
28 if ( ! is_email( $atts['address'] ) ) {
29 return '';
30 }
31
32 return sprintf(
33 '<a href="mailto:%1$s">%1$s</a>',
34 antispambot( $atts['address'], 1 )
35 );
36 }
37}
38
39MySite_Shortcodes::init();

Placez ce fichier dans wp-content/plugins/mysite-shortcodes/mysite-shortcodes.php et activez l’extension dans le panneau d’administration. Le shortcode [mysite_email address="hello@example.com"] produira un lien protégé contre les robots spammeurs; la fonction antispambot encode les caractères de l’email en entités HTML.

Pourquoi une classe, et non un ensemble de fonctions. L’espace de noms: trois shortcodes dans une classe n’entreront pas en conflit avec des fonctions tierces. Ajoutez à cela l’autochargement et un code plus lisible si l’extension grandit jusqu’à une douzaine de shortcodes.

Tester un shortcode avant publication

Après avoir ajouté le code, vérifiez trois scénarios:

  • Shortcode sans attribut. Simplement [mysite_cta], il doit s’afficher avec les valeurs par défaut (texte «En savoir plus», lien #).
  • Shortcode avec attributs. Un jeu complet de paramètres, toutes les valeurs sont prises en compte et affichées correctement.
  • Erreur dans un attribut. Un email invalide dans [mysite_email], la fonction retourne silencieusement une chaîne vide au lieu de casser la page.

Important: n’utilisez jamais echo dans une fonction de rappel. Un shortcode doit retourner une chaîne via return. Si vous produisez du HTML avec echo, il apparaîtra non pas à l’emplacement du shortcode, mais tout en haut de la page, car WordPress exécute le rendu des shortcodes avant la sortie du contenu. Même logique que pour les filtres: la fonction rend une valeur, et le moteur décide lui-même où l’insérer.

Une seconde nuance: si le shortcode ne s’affiche pas (vous voyez [mysite_cta] sous forme de texte, pas de bouton), vérifiez que la fonction est bien enregistrée sur le hook init, et non directement dans le corps de l’extension. Sans init, le tableau global $shortcode_tags n’est peut-être pas encore prêt à accepter de nouvelles balises.

Shortcode dans un thème ou dans une extension: que choisir

Critère

functions.php du thème

Extension séparée

Vitesse de démarrage

Plus rapide - fichier déjà chargé

Légèrement plus lent - fichier séparé

Portabilité

Lié au thème

Fonctionne avec n’importe quel thème

Survie aux mises à jour

Perdu lors d’une mise à jour du thème

Vit de manière indépendante

Confort d’édition

Apparence → Éditeur de fichiers du thème

Éditeur d’extension ou FTP

Pour combien de shortcodes

1 à 3

4 et plus

La règle: commencez par le functions.php sur un site de test, construisez trois shortcodes, puis migrez-les dans une extension. Une mise à jour du thème six mois plus tard n’enterrera pas votre logique, et vous pourrez transférer les shortcodes vers un autre projet en une minute.

⁉️🤔 FAQ

Quelle est la différence entre un shortcode et un bloc Gutenberg?

Un shortcode est une balise textuelle entre crochets qui est traitée côté serveur. Un bloc est un composant visuel de l’éditeur, un composant React avec des réglages dans la barre latérale. Les shortcodes sont apparus dans WordPress 2.5 (2008), les blocs dans la version 5.0 (2018). Aujourd’hui, les blocs constituent le moyen principal d’insérer du contenu dynamique, mais les shortcodes restent pertinents: ils sont plus simples à développer, ne nécessitent aucune connaissance en JavaScript et fonctionnent dans n’importe quel éditeur, y compris l’éditeur classique et les constructeurs de pages.

Un shortcode est une balise textuelle que WordPress remplace par le résultat d’une fonction PHP lors du rendu de la page. Contrairement à un bloc Gutenberg, un shortcode n’a pas d’interface visuelle dans l’éditeur: le gestionnaire de contenu écrit [myshortcode] sous forme de texte et voit le HTML final sur le front-end.

Puis-je utiliser un shortcode à l’intérieur d’un autre shortcode?

Oui. Si la fonction de rappel du shortcode englobant traite le contenu imbriqué avec do_shortcode(), les shortcodes internes fonctionneront correctement: [notice][current_year][/notice] affichera un bloc stylisé avec l’année en cours. Sans do_shortcode(), le shortcode imbriqué restera sous forme de texte entre crochets.

Les shortcodes imbriqués sont traités de manière récursive: WordPress parcourt la chaîne plusieurs fois jusqu’à ce qu’il ne reste plus de balises non traitées. Mais pour que cela fonctionne, le shortcode englobant doit explicitement appeler do_shortcode($content). Sinon, la chaîne [current_year] restera sous forme de texte au lieu de se transformer en «2026».

Pourquoi mon shortcode ne fonctionne-t-il pas et s’affiche-t-il sous forme de texte entre crochets?

Trois raisons fréquentes. Premièrement: add_shortcode est appelé avant le hook init, déplacez l’enregistrement à l’intérieur de add_action('init', ...). Deuxièmement: une faute de frappe dans le nom de la balise, [my_shortcode] dans l’éditeur mais myshortcode est enregistré. Troisièmement: la fonction de rappel utilise echo au lieu de return, donc le résultat s’affiche en haut de la page et l’emplacement du shortcode est vide.

Le coupable le plus fréquent est l’utilisation de echo au lieu de return dans la fonction de rappel. WordPress appelle les gestionnaires de shortcodes avant d’afficher le contenu principal, donc le résultat du echo atteint le tampon de sortie avant l’en-tête de la page. Ouvrez le code source de la page (Ctrl+U): si vous voyez le HTML du shortcode tout en haut, avant <html>, c’est exactement le problème.

Dois-je échapper la sortie d’un shortcode?

Absolument. Un shortcode accepte des attributs provenant de l’éditeur, donc potentiellement de tout utilisateur disposant des droits d’auteur ou d’éditeur. esc_html() pour le texte, esc_url() pour les liens, esc_attr() pour les attributs HTML. L’exception concerne le cas où vous retournez intentionnellement du balisage HTML (comme <div class="notice">). Mais même dans ce cas, échappez les attributs à l’intérieur du balisage.

Oui, l’échappement est obligatoire pour tout ce qui provient des attributs de shortcode ou d’une saisie utilisateur. Même si aujourd’hui vous êtes le seul à insérer des shortcodes, demain un gestionnaire de contenu obtiendra un accès éditeur. esc_html() pour le texte, esc_url() pour les liens, esc_attr() pour les attributs HTML protègent contre les failles XSS accidentelles ou intentionnelles.

Combien de shortcodes puis-je enregistrer sur un seul site?

Il n’y a pas de limite technique: $shortcode_tags est un tableau PHP classique, vous atteindrez la limite de mémoire du serveur bien après celle du bon sens. En pratique, au-delà de 15 à 20 shortcodes personnalisés, il est utile de se demander: est-il temps de transformer certains d’entre eux en blocs Gutenberg? Conservez les shortcodes ayant une logique unique (obfuscation d’email, affichage conditionnel par rôle). Pour les shortcodes qui se contentent de styliser du texte ([highlight]), il est préférable d’utiliser un style de bloc ou une classe CSS.

Techniquement, autant que vous le souhaitez: le tableau $shortcode_tags n’a pas de limite artificielle. En pratique, plus de 20 à 25 shortcodes sur un même site suggèrent qu’une partie de la logique devrait être migrée vers des blocs. Chaque shortcode ajoute une charge d’analyse du contenu: avant l’affichage, WordPress parcourt l’intégralité du tableau des balises enregistrées et recherche des correspondances dans le texte de la publication.

Faut-il écrire ses propres shortcodes ou les plugins prêts à l’emploi suffisent-ils?

Un plugin prêt à l’emploi couvre la plupart des tâches courantes: formulaires, Contact Form 7, tableaux, TablePress, grilles, n’importe quel constructeur de pages. Un shortcode personnalisé est nécessaire lorsque la logique est spécifique à votre site et qu’aucune solution existante ne répond au besoin: afficher un champ personnalisé exactement à cet endroit de la page, la date du prochain webinaire depuis la base de données, un message d’accueil personnalisé selon le rôle de l’utilisateur.

En bref: pour une fonctionnalité standard, utilisez un plugin et ne codez pas. Pour une logique unique, add_shortcode + functions.php ou un mini-plugin. Le code de chacun des exemples ci-dessus fait moins de dix lignes. Une fois que vous maîtrisez ces trois modèles (simple, avec attributs, avec contenu imbriqué), vous couvrirez la grande majorité des tâches pour lesquelles on écrit des shortcodes personnalisés.