Un besoin revient régulièrement sur nos projets : le widget natif Image d’Elementor fait tout ce qu’il faut, sauf proposer un contrôle pour ajouter une légende personnalisée sous l’image, différente du texte alternatif. Réécrire tout le widget pour une seule option serait disproportionné. La bonne solution consiste à injecter un contrôle supplémentaire directement dans le widget existant, sans toucher à son code source.
Elementor permet cela via une famille de hooks d’action rattachés à chaque section de contrôles d’un widget, combinée à un hook de rendu pour exploiter la valeur ajoutée. Voici la méthode complète, appliquée à cet exemple de légende d’image.
Cibler la bonne section avec before_section_end
Chaque widget Elementor organise ses contrôles en sections (Contenu, Style, Avancé, chacune subdivisée). Le hook elementor/element/{element_name}/{section_id}/before_section_end se déclenche juste avant la fermeture d’une section précise, ce qui permet d’y insérer un nouveau contrôle au bon endroit visuel dans l’éditeur.
add_action( 'elementor/element/image/section_image/before_section_end', function( $element, $args ) {
$element->add_control(
'wpm_legende',
[
'label' => __( 'Légende personnalisée', 'wpm' ),
'type' => \Elementor\Controls_Manager::TEXT,
'default' => '',
]
);
}, 10, 2 );
Ici, image désigne le nom interne du widget cible, et section_image l’identifiant de la section de contrôles dans laquelle insérer le champ. Ces identifiants se retrouvent en consultant le code source du widget natif dans le dossier elementor/includes/widgets/.

Exploiter la valeur au moment du rendu
Ajouter un contrôle ne modifie rien à lui seul : sans code pour lire sa valeur et l’afficher, le champ reste purement décoratif dans l’éditeur. Il faut donc intervenir au rendu, via le hook elementor/frontend/before_render ou directement en surchargeant partiellement le template du widget si Elementor l’expose, ce qui n’est pas toujours le cas pour les widgets natifs.
Pour un contrôle simple comme une légende texte, la solution la plus robuste reste d’utiliser le hook elementor/frontend/after_render, qui permet d’ajouter du HTML après le rendu natif du widget, sans avoir à reproduire toute sa logique d’affichage :
add_action( 'elementor/frontend/after_render', function( $element ) {
if ( 'image' !== $element->get_name() ) {
return;
}
$legende = $element->get_settings_for_display( 'wpm_legende' );
if ( ! empty( $legende ) ) {
echo '<p class="wpm-legende-image">' . esc_html( $legende ) . '</p>';
}
} );
Pourquoi éviter de surcharger tout le widget
Une alternative existe : copier le widget natif dans un fichier personnalisé, l’étendre en PHP, et l’enregistrer sous un nouveau nom. Cette approche fonctionne, mais elle a un coût de maintenance important : chaque mise à jour d’Elementor qui modifie le widget original n’est plus répercutée automatiquement sur la copie, qui finit par diverger silencieusement.
| Approche | Maintenance | Effort initial |
|---|---|---|
| Hook before_section_end + after_render | Faible, suit les mises à jour du widget natif | Quelques lignes de code |
| Copie et extension du widget natif | Élevée, divergence progressive | Réécriture complète du widget |
Trouver les bons identifiants de section
Pour identifier le nom exact d’une section (section_image, section_title…) sans fouiller le code source à chaque fois, un moyen rapide consiste à activer temporairement le mode debug PHP et à inspecter l’arborescence des contrôles retournée par $widget->get_controls() sur le widget concerné, ou à consulter directement les sources d’Elementor sur son dépôt GitHub officiel, où chaque widget natif est documenté par son code.
Cette technique de hook avant/après rendu nous a évité, sur des dizaines de projets, de dupliquer des widgets natifs pour une seule fonctionnalité manquante — ce qui aurait multiplié les points de maintenance sans réel bénéfice.
En résumé
Ajouter un contrôle à un widget natif d’Elementor ne demande ni fork ni réécriture : une simple combinaison de before_section_end pour insérer le champ dans l’éditeur, et d’un hook de rendu pour exploiter sa valeur côté public, suffit dans la grande majorité des cas. Cette méthode reste alignée avec les mises à jour futures du widget natif, contrairement à une copie complète qui finit toujours par diverger.