# Créer un widget Elementor personnalisé : la classe Widget_Base pas à pas

> Tutoriel complet pour développer votre propre widget Elementor en PHP : structure de la classe, contrôles, rendu, et enregistrement auprès du plugin.

- Auteur : Clément Hadrot
- Publié le : 2020-07-23
- Mis à jour le : 2020-07-23
- Catégorie : Elementor
- URL : https://wpmoderne.dev.wordpress-developpement.fr/elementor/creer-widget-elementor-personnalise-widget-base/

## L’essentiel

- Structurer une classe qui étend Widget_Base
- Ajouter des contrôles avec register_controls()
- Enregistrer le widget via le hook dédié

Les widgets natifs d'Elementor couvrent beaucoup de besoins, mais dès qu'un projet a des exigences spécifiques — afficher une donnée métier, un bloc d'avis clients formaté à votre façon, un composant réutilisable sur plusieurs sites — il devient plus efficace de développer son propre widget plutôt que de bricoler avec les widgets existants. Bonne nouvelle : Elementor expose une API PHP claire pour cela, centrée sur la classe abstraite `\Elementor\Widget_Base`.

Dans ce tutoriel, nous allons construire un widget personnalisé complet, du squelette de la classe jusqu'à son enregistrement dans l'éditeur, avec un exemple concret : un widget « Bloc d'information » affichant un titre, un texte et une couleur de fond configurables. L'objectif est de vous donner une base solide et fonctionnelle que vous pourrez ensuite adapter à vos propres besoins.

## Où placer le code : plugin dédié plutôt que fonctions.php

Avant d'écrire le widget lui-même, un point important : créez toujours vos widgets personnalisés dans un plugin dédié plutôt que dans le `functions.php` du thème. Un widget lié à un thème disparaît si le thème change ; un plugin, lui, survit à toutes les évolutions du design du site. La structure minimale ressemble à un plugin WordPress classique, avec un fichier principal qui vérifie qu'Elementor est actif avant de charger quoi que ce soit.

```
<?php
/**
 * Plugin Name: Mon Widget Elementor
 * Description: Widget personnalise pour Elementor
 * Version: 1.0.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

function mon_widget_charger_fichier() {
    require_once __DIR__ . '/widgets/bloc-info-widget.php';
}
add_action( 'elementor/widgets/register', 'mon_widget_charger_fichier' );
```

Le hook `elementor/widgets/register` est le point d'entrée fourni par Elementor pour enregistrer de nouveaux widgets. Il s'exécute une fois qu'Elementor a initialisé son gestionnaire de widgets, ce qui garantit que la classe `\Elementor\Widget_Base` est bien disponible au moment du chargement de votre fichier.

## La structure de la classe Widget_Base

Un widget Elementor est une classe PHP qui étend `\Elementor\Widget_Base` et qui doit implémenter un petit nombre de méthodes obligatoires : `get_name()`, `get_title()`, `get_icon()`, `get_categories()`, `register_controls()` et `render()`. Voici le squelette complet de notre widget « Bloc d'information » :

```
<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

use Elementor\Widget_Base;
use Elementor\Controls_Manager;

class Bloc_Info_Widget extends Widget_Base {

    public function get_name() {
        return 'bloc_info';
    }

    public function get_title() {
        return __( 'Bloc d\'information', 'mon-widget' );
    }

    public function get_icon() {
        return 'eicon-info-circle-o';
    }

    public function get_categories() {
        return [ 'basic' ];
    }

    protected function register_controls() {
        $this->start_controls_section(
            'section_contenu',
            [
                'label' => __( 'Contenu', 'mon-widget' ),
            ]
        );

        $this->add_control(
            'titre',
            [
                'label'   => __( 'Titre', 'mon-widget' ),
                'type'    => Controls_Manager::TEXT,
                'default' => __( 'Titre par defaut', 'mon-widget' ),
            ]
        );

        $this->add_control(
            'texte',
            [
                'label'   => __( 'Texte', 'mon-widget' ),
                'type'    => Controls_Manager::TEXTAREA,
                'default' => __( 'Ecrivez votre texte ici.', 'mon-widget' ),
            ]
        );

        $this->add_control(
            'couleur_fond',
            [
                'label'   => __( 'Couleur de fond', 'mon-widget' ),
                'type'    => Controls_Manager::COLOR,
                'default' => '#f5f5f5',
            ]
        );

        $this->end_controls_section();
    }

    protected function render() {
        $settings = $this->get_settings_for_display();
        ?>
        <div class="bloc-info" style="background-color: <?php echo esc_attr( $settings['couleur_fond'] ); ?>;">
            <h3><?php echo esc_html( $settings['titre'] ); ?></h3>
            <p><?php echo esc_html( $settings['texte'] ); ?></p>
        </div>
        <?php
    }
}
```

> L'essentiel à retenir : Structurer une classe qui étend Widget_Base ; Ajouter des contrôles avec register_controls() ; Enregistrer le widget via le hook dédié

## Comprendre chaque méthode

Chaque méthode a un rôle précis dans le fonctionnement du widget :

- `get_name()` retourne un identifiant unique en minuscules, utilisé en interne par Elementor. Il ne doit jamais entrer en conflit avec un autre widget installé.
- `get_title()` définit le libellé affiché dans le panneau des widgets, visible par l'utilisateur final.
- `get_icon()` référence une icône parmi celles fournies nativement par Elementor (préfixe `eicon-`), affichée dans le panneau.
- `get_categories()` place le widget dans une catégorie existante du panneau, comme `basic`, ou une catégorie personnalisée si vous en créez une.
- `register_controls()` construit les champs de réglage visibles dans l'éditeur, regroupés en sections via `start_controls_section()` et `end_controls_section()`, chaque champ étant ajouté avec `add_control()` et un type issu de `\Elementor\Controls_Manager`.
- `render()` génère le HTML final affiché côté site, en récupérant les réglages avec `get_settings_for_display()`.

## Sécuriser et enrichir le rendu

Le réflexe à conserver systématiquement dans `render()` est l'échappement des données affichées, avec `esc_html()` pour du texte simple, `esc_attr()` pour des attributs HTML, ou `wp_kses_post()` si le champ autorise du HTML enrichi. C'est une exigence de sécurité, pas une option, même si le contenu provient d'un champ que seul l'administrateur peut modifier.

Vous pouvez ensuite enrichir le widget avec d'autres types de contrôles : `Controls_Manager::SELECT` pour un menu déroulant, `Controls_Manager::MEDIA` pour une image, ou une section de style séparée avec `start_controls_section()` en précisant `'tab' => Controls_Manager::TAB_STYLE` pour distinguer clairement les réglages de contenu des réglages visuels dans l'éditeur.

> Testez toujours votre widget avec des valeurs vides ou extrêmes (texte très long, champ non rempli) avant de le livrer. Un widget qui casse la mise en page dès que le client vide un champ donne une mauvaise image de tout le travail réalisé autour.

## En résumé

Créer un widget Elementor personnalisé repose sur une API claire et stable : une classe qui étend `Widget_Base`, quelques méthodes d'identification, une méthode `register_controls()` pour construire l'interface de réglage, et une méthode `render()` pour générer le HTML final. Enregistré via le hook `elementor/widgets/register`, ce widget devient immédiatement disponible dans le panneau de l'éditeur, au même titre que les widgets natifs. C'est une compétence particulièrement rentable dès qu'un projet a des besoins récurrents et spécifiques que les widgets standards ne couvrent pas.
