# Développer un widget imbriqué Elementor avec Widget_Nested_Base

> Créer un widget Elementor à enfants modifiables, sur le modèle des nested elements, avec la classe Widget_Nested_Base et son pendant JavaScript.

- Auteur : Clément Hadrot
- Publié le : 2023-10-19
- Mis à jour le : 2023-10-19
- Catégorie : Elementor
- URL : https://wpmoderne.dev.wordpress-developpement.fr/elementor/widget-imbrique-elementor-widget-nested-base/

## L’essentiel

- Widget_Nested_Base gère un conteneur avec des enfants imbriqués
- Chaque enfant reste un vrai container éditable
- Le rendu JavaScript doit répliquer fidèlement le PHP

Depuis l'introduction des nested elements (Tabs et Accordion imbriqués), Elementor propose une base spécifique pour construire ce type de widget : `Widget_Nested_Base`. Contrairement à un widget classique qui hérite de `Widget_Base` et affiche un contenu figé par ses propres contrôles, un widget imbriqué délègue une partie de son contenu à des containers enfants que l'utilisateur peut remplir librement avec n'importe quel widget Elementor.

Pour un client qui voulait un widget « Étapes » présentant un processus en plusieurs blocs numérotés, chacun pouvant contenir un texte libre, une image ou même un bouton, la solution la plus propre était de construire ce widget sur ce modèle plutôt que de multiplier les champs répéteur classiques.

## Structure de base de la classe PHP

Un widget imbriqué étend `\Elementor\Widget_Nested_Base` et doit définir le nombre de conteneurs enfants ainsi que leurs identifiants via la méthode `get_default_children_elements` ou par un contrôle répéteur qui pilote leur nombre :

```
class Widget_Etapes extends \Elementor\Widget_Nested_Base {

    public function get_name() {
        return 'widget-etapes';
    }

    public function get_title() {
        return __( 'Étapes', 'mon-theme' );
    }

    public function get_icon() {
        return 'eicon-numbered-list';
    }

    protected function register_controls() {
        $repeater = new \Elementor\Repeater();
        $repeater->add_control(
            'titre_etape',
            [
                'label' => __( 'Titre de l\'étape', 'mon-theme' ),
                'type' => \Elementor\Controls_Manager::TEXT,
                'default' => __( 'Étape', 'mon-theme' ),
            ]
        );

        $this->add_control(
            'etapes',
            [
                'label' => __( 'Étapes', 'mon-theme' ),
                'type' => \Elementor\Controls_Manager::REPEATER,
                'fields' => $repeater->get_controls(),
                'prevent_empty' => true,
                'default' => [
                    [ 'titre_etape' => __( 'Analyse', 'mon-theme' ) ],
                    [ 'titre_etape' => __( 'Conception', 'mon-theme' ) ],
                ],
            ]
        );
    }
}
```

## Récupérer et rendre les containers enfants

La particularité de `Widget_Nested_Base` tient à sa méthode `get_default_children_elements`, qui définit combien de containers enfants existent, en fonction par exemple du nombre d'entrées du répéteur. Chaque container enfant reçoit un identifiant stable qu'il faut utiliser pour son rendu PHP :

```
protected function get_default_children_elements() {
    $repeater_items = $this->get_settings( 'etapes' );
    $children = [];

    foreach ( $repeater_items as $index => $item ) {
        $children[] = [
            '_element_id' => 'etape-' . $index,
        ];
    }

    return $children;
}

protected function content_template() {
    // Le rendu JS répète la même logique via Backbone/Marionette.
}
```

> L'essentiel à retenir : Widget_Nested_Base gère un conteneur avec des enfants imbriqués ; Chaque enfant reste un vrai container éditable ; Le rendu JavaScript doit répliquer fidèlement le PHP

Le rendu final du widget doit ensuite parcourir les enfants avec `print_child( $index )` pour afficher le container correspondant à l'endroit voulu dans le HTML :
