Les contrôles avancés fournis nativement par Elementor (texte, couleur, slider, répéteur…) couvrent la quasi-totalité des besoins courants. Mais sur un projet récent, nous avions besoin d’un contrôle de sélection de coordonnées géographiques simplifiées, avec un rendu spécifique dans l’éditeur — un cas qu’aucun contrôle natif ne couvrait de façon satisfaisante. La solution est allée jusqu’à écrire un nouveau type de contrôle personnalisé, réutilisable sur tous les widgets du site.
Contrairement à l’ajout d’un simple contrôle existant sur un widget (une opération bien plus courante), créer un nouveau type de contrôle demande d’étendre la classe abstraite Base_Data_Control et de fournir un template JavaScript Underscore pour le rendu dans l’éditeur. Voici la structure complète, sans reprendre ici l’usage des contrôles déjà fournis par Elementor.
La classe PHP du contrôle
Tout contrôle de type « donnée » (une valeur simple stockée dans les settings du widget, par opposition aux contrôles purement visuels comme une section ou un message d’alerte) étend \Elementor\Base_Data_Control. Trois méthodes sont à implémenter :
<?php
class Control_Coordonnees extends \Elementor\Base_Data_Control {
public function get_type() {
return 'wpm-coordonnees';
}
public function get_default_value() {
return [ 'lat' => '', 'lng' => '' ];
}
protected function get_default_settings() {
return [
'label_block' => true,
];
}
}
get_type() définit l’identifiant unique utilisé dans add_control(), get_default_value() fixe la structure de données par défaut (ici un tableau latitude/longitude), et get_default_settings() permet de préciser des options d’affichage communes à toutes les instances de ce contrôle.
Le template JavaScript Underscore
Le rendu visuel du contrôle dans l’éditeur ne se fait pas en PHP mais en JavaScript, via un template Underscore enregistré côté script. C’est cette partie qui dessine réellement les champs que verra l’utilisateur dans le panneau Elementor :
<script type="text/template" id="tmpl-wpm-control-coordonnees">
<# if ( data.label ) { #>
<label class="elementor-control-title">{{{ data.label }}}</label>
<# } #>
<div class="elementor-control-input-wrapper">
<input type="text" data-setting="lat" placeholder="Latitude" />
<input type="text" data-setting="lng" placeholder="Longitude" />
</div>
</script>

Enregistrer le contrôle auprès d’Elementor
Une fois la classe et le template prêts, l’enregistrement se fait via le hook elementor/controls/register, similaire dans son fonctionnement au hook d’enregistrement des widgets :
add_action( 'elementor/controls/register', function( $controls_manager ) {
require_once __DIR__ . '/controls/class-control-coordonnees.php';
$controls_manager->register( new Control_Coordonnees() );
} );
add_action( 'elementor/editor/before_enqueue_scripts', function() {
wp_enqueue_script(
'wpm-control-coordonnees',
plugins_url( 'assets/js/control-coordonnees.js', __FILE__ ),
[ 'elementor-editor' ],
'1.0.0',
true
);
} );
Utiliser le contrôle dans un widget
Une fois enregistré, le contrôle s’utilise exactement comme un contrôle natif, en indiquant son type dans add_control() :
$this->add_control(
'wpm_position',
[
'label' => __( 'Position', 'wpm' ),
'type' => 'wpm-coordonnees',
]
);
Ce même contrôle devient alors disponible sur n’importe quel autre widget du site qui en aurait besoin, sans avoir à réécrire sa logique de rendu à chaque fois — c’est tout l’intérêt de créer un type de contrôle plutôt que de bricoler une solution locale à un seul widget.
| Fichier | Rôle |
|---|---|
| Classe PHP (Base_Data_Control) | Définit le type, la valeur par défaut, les réglages |
| Template JS Underscore | Dessine le champ dans l’éditeur Elementor |
Créer un type de contrôle personnalisé reste une opération rare, réservée aux besoins qui reviennent sur plusieurs widgets. Pour un seul champ isolé, un contrôle natif suffit presque toujours.
En résumé
Un contrôle Elementor personnalisé repose sur deux briques indissociables : une classe PHP qui étend Base_Data_Control pour la logique de stockage, et un template JavaScript Underscore pour le rendu dans l’éditeur. L’enregistrement via elementor/controls/register rend ensuite ce contrôle disponible sur tous les widgets du site, un investissement qui se justifie dès qu’un même besoin de saisie se répète sur plusieurs composants.