Si vous n’avez pas déjà utilisé le plugin Elementor – vous devriez le faire. J’ai utilisé beaucoup de constructeurs de sites plug-n-play à mon époque et celui-ci fait exploser les autres. Mais vous êtes ici pour apprendre à créer des widgets Elementor personnalisés et devinez quoi ? C’est du gâteau !

Dans cet article, nous allons construire un widget Elementor simple et personnalisé qui permet à l’utilisateur de modifier le texte, les images et les styles à la fois dans les paramètres du widget et en ligne ! Nous appellerons ce widget, Elementor Zendawesome.

Créer un plugin WordPress pour englober notre Widget Elementor

Je ne peux pas vous dire combien de fois j’ai vu des implémentations personnalisées faites dans le thème – ce qui est possible, mais pas très bien pour l’approche composant. Construire un plugin vous permet d’avoir une séparation du code pour que votre PHP, CSS et JS existants ne soient pas mélangés dans le code de votre thème. Mieux encore, vous pouvez charger conditionnellement vos ressources frontales uniquement aux endroits où votre widget personnalisé apparaîtra, ce qui vous donnera un coup de pouce en termes de performances. Alors commençons par là, créons notre plugin Elementor Zendawesome :

  1. Dans wp-content/plugins, créez un répertoire appelé elementor-zendawesome.
  2. Dans le répertoire elementor-zendawesome, ajoutez les fichiers et répertoires suivants :
    1. elementor-zendawesome.php – initialise le plugin et vérifie les exigences nécessaires
    2. widgets/zendawesome.php – notre widget Zendawesome Elementor personnalisé
    3. assets/js/zendawesome.js – quelques JS pour notre widget personnalisé
    4. assets/css – répertoire pour nos fichiers CSS spécifiques au plugin

Fichier elementor-zendawesome.php

<?php
/**
 * Plugin Name: Elementor Zendawesome
 * Description: A simple Elementor Zendawesome plugin that holds some most excellent custom widgets.
 * Plugin URI:  https://www.zendevs.xyz/comment-creer-son-widget-elementor-personnalise/
 * Version:     1.0.0
 * Author:      Siddhy
 * Author URI:  https://www.zendevs.xyz
 * Text Domain: elementor-zendawesome
 * File :       elementor-zendawesome.php
 */
 
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
 
/**
 * Main Elementor Zendawesome Class
 *
 * The init class that runs the Elementor Zendawesome plugin.
 * Intended To make sure that the plugin's minimum requirements are met.
 *
 * You should only modify the constants to match your plugin's needs.
 *
 * Any custom code should go inside Plugin Class in the plugin.php file.
 * @since 1.0.0
 */
final class Elementor_Zendawesome {
 
  /**
   * Plugin Version
   *
   * @since 1.0.0
   * @var string The plugin version.
   */
  const VERSION = '1.0.0';
 
  /**
   * Minimum Elementor Version
   *
   * @since 1.0.0
   * @var string Minimum Elementor version required to run the plugin.
   */
  const MINIMUM_ELEMENTOR_VERSION = '2.0.0';
 
  /**
   * Minimum PHP Version
   *
   * @since 1.0.0
   * @var string Minimum PHP version required to run the plugin.
   */
  const MINIMUM_PHP_VERSION = '7.0';
 
  /**
   * Constructor
   *
   * @since 1.0.0
   * @access public
   */
  public function __construct() {
 
    // Load translation
    add_action( 'init', array( $this, 'i18n' ) );
 
    // Init Plugin
    add_action( 'plugins_loaded', array( $this, 'init' ) );
  }
 
  /**
   * Load Textdomain
   *
   * Load plugin localization files.
   * Fired by `init` action hook.
   *
   * @since 1.2.0
   * @access public
   */
  public function i18n() {
    load_plugin_textdomain( 'elementor-zendawesome' );
  }
 
  /**
   * Initialize the plugin
   *
   * Validates that Elementor is already loaded.
   * Checks for basic plugin requirements, if one check fail don't continue,
   * if all check have passed include the plugin class.
   *
   * Fired by `plugins_loaded` action hook.
   *
   * @since 1.2.0
   * @access public
   */
  public function init() {
 
    // Check if Elementor installed and activated
    if ( ! did_action( 'elementor/loaded' ) ) {
      add_action( 'admin_notices', array( $this, 'admin_notice_missing_main_plugin' ) );
      return;
    }
 
    // Check for required Elementor version
    if ( ! version_compare( ELEMENTOR_VERSION, self::MINIMUM_ELEMENTOR_VERSION, '>=' ) ) {
      add_action( 'admin_notices', array( $this, 'admin_notice_minimum_elementor_version' ) );
      return;
    }
 
    // Check for required PHP version
    if ( version_compare( PHP_VERSION, self::MINIMUM_PHP_VERSION, '<' ) ) {
      add_action( 'admin_notices', array( $this, 'admin_notice_minimum_php_version' ) );
      return;
    }
 
    // Once we get here, We have passed all validation checks so we can safely include our plugin
    require_once( 'plugin.php' );
  }
 
  /**
   * Admin notice
   *
   * Warning when the site doesn't have Elementor installed or activated.
   *
   * @since 1.0.0
   * @access public
   */
  public function admin_notice_missing_main_plugin() {
    if ( isset( $_GET['activate'] ) ) {
      unset( $_GET['activate'] );
    }
 
    $message = sprintf(
      /* translators: 1: Plugin name 2: Elementor */
      esc_html__( '"%1$s" requires "%2$s" to be installed and activated.', 'elementor-zendawesome' ),
      '<strong>' . esc_html__( 'Elementor Zendawesome', 'elementor-zendawesome' ) . '</strong>',
      '<strong>' . esc_html__( 'Elementor', 'elementor-zendawesome' ) . '</strong>'
    );
 
    printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );
  }
 
  /**
   * Admin notice
   *
   * Warning when the site doesn't have a minimum required Elementor version.
   *
   * @since 1.0.0
   * @access public
   */
  public function admin_notice_minimum_elementor_version() {
    if ( isset( $_GET['activate'] ) ) {
      unset( $_GET['activate'] );
    }
 
    $message = sprintf(
      /* translators: 1: Plugin name 2: Elementor 3: Required Elementor version */
      esc_html__( '"%1$s" requires "%2$s" version %3$s or greater.', 'elementor-zendawesome' ),
      '<strong>' . esc_html__( 'Elementor Zendawesome', 'elementor-zendawesome' ) . '</strong>',
      '<strong>' . esc_html__( 'Elementor', 'elementor-zendawesome' ) . '</strong>',
      self::MINIMUM_ELEMENTOR_VERSION
    );
 
    printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );
  }
 
  /**
   * Admin notice
   *
   * Warning when the site doesn't have a minimum required PHP version.
   *
   * @since 1.0.0
   * @access public
   */
  public function admin_notice_minimum_php_version() {
    if ( isset( $_GET['activate'] ) ) {
      unset( $_GET['activate'] );
    }
 
    $message = sprintf(
      /* translators: 1: Plugin name 2: PHP 3: Required PHP version */
      esc_html__( '"%1$s" requires "%2$s" version %3$s or greater.', 'elementor-zendawesome' ),
      '<strong>' . esc_html__( 'Elementor Zendawesome', 'elementor-zendawesome' ) . '</strong>',
      '<strong>' . esc_html__( 'PHP', 'elementor-zendawesome' ) . '</strong>',
      self::MINIMUM_PHP_VERSION
    );
 
    printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );
  }
}
 
// Instantiate Elementor_Zendawesome.
new Elementor_Zendawesome();

Fichier plugin.php

<?php
namespace ElementorZendawesome;
 
/**
 * Class Plugin
 *
 * Main Plugin class
 * @since 1.0.0
 * File : plugin.php
 */
class Plugin {
 
  /**
   * Instance
   *
   * @since 1.0.0
   * @access private
   * @static
   *
   * @var Plugin The single instance of the class.
   */
  private static $_instance = null;
 
  /**
   * Instance
   *
   * Ensures only one instance of the class is loaded or can be loaded.
   *
   * @since 1.2.0
   * @access public
   *
   * @return Plugin An instance of the class.
   */
  public static function instance() {
    if ( is_null( self::$_instance ) ) {
      self::$_instance = new self();
    }
           
    return self::$_instance;
  }
 
  /**
   * widget_scripts
   *
   * Load required plugin core files.
   *
   * @since 1.2.0
   * @access public
   */
  public function widget_scripts() {
    wp_register_script( 'elementor-zendawesome', plugins_url( '/assets/js/zendawesome.js', __FILE__ ), [ 'jquery' ], false, true );
  }
 
  /**
   * Include Widgets files
   *
   * Load widgets files
   *
   * @since 1.2.0
   * @access private
   */
  private function include_widgets_files() {
    require_once( __DIR__ . '/widgets/zendawesome.php' );
  }
 
  /**
   * Register Widgets
   *
   * Register new Elementor widgets.
   *
   * @since 1.2.0
   * @access public
   */
  public function register_widgets() {
    // Its is now safe to include Widgets files
    $this->include_widgets_files();
 
    // Register Widgets
    \Elementor\Plugin::instance()->widgets_manager->register_widget_type( new Widgets\Zendawesome() );
  }
 
  /**
   *  Plugin class constructor
   *
   * Register plugin action hooks and filters
   *
   * @since 1.2.0
   * @access public
   */
  public function __construct() {
 
    // Register widget scripts
    add_action( 'elementor/frontend/after_register_scripts', [ $this, 'widget_scripts' ] );
 
    // Register widgets
    add_action( 'elementor/widgets/widgets_registered', [ $this, 'register_widgets' ] );
  }
}
 
// Instantiate Plugin Class
Plugin::instance();

Fichier widgets/zendawesome.php

<?php
namespace ElementorZendawesome\Widgets;
 
use Elementor\Widget_Base;
use Elementor\Controls_Manager;
 
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
 
/**
 * @since 1.1.0
 * File : widgets/zendawesome.php
 */
class Zendawesome extends Widget_Base {
 
  /**
   * Retrieve the widget name.
   *
   * @since 1.1.0
   *
   * @access public
   *
   * @return string Widget name.
   */
  public function get_name() {
    return 'zendawesome';
  }
 
  /**
   * Retrieve the widget title.
   *
   * @since 1.1.0
   *
   * @access public
   *
   * @return string Widget title.
   */
  public function get_title() {
    return __( 'Zendawesome', 'elementor-zendawesome' );
  }
 
  /**
   * Retrieve the widget icon.
   *
   * @since 1.1.0
   *
   * @access public
   *
   * @return string Widget icon.
   */
  public function get_icon() {
    return 'fa fa-pencil';
  }
 
  /**
   * Retrieve the list of categories the widget belongs to.
   *
   * Used to determine where to display the widget in the editor.
   *
   * Note that currently Elementor supports only one category.
   * When multiple categories passed, Elementor uses the first one.
   *
   * @since 1.1.0
   *
   * @access public
   *
   * @return array Widget categories.
   */
  public function get_categories() {
    return [ 'general' ];
  }
 
  /**
   * Register the widget controls.
   *
   * Adds different input fields to allow the user to change and customize the widget settings.
   *
   * @since 1.1.0
   *
   * @access protected
   */
  protected function _register_controls() {
    $this->start_controls_section(
      'section_content',
      [
        'label' => __( 'Content', 'elementor-zendawesome' ),
      ]
    );
 
    $this->add_control(
      'title',
      [
        'label' => __( 'Title', 'elementor-zendawesome' ),
        'type' => Controls_Manager::TEXT,
        'default' => __( 'Title', 'elementor-zendawesome' ),
      ]
    );
 
    $this->add_control(
      'description',
      [
        'label' => __( 'Description', 'elementor-zendawesome' ),
        'type' => Controls_Manager::TEXTAREA,
        'default' => __( 'Description', 'elementor-zendawesome' ),
      ]
    );
 
    $this->add_control(
      'content',
      [
        'label' => __( 'Content', 'elementor-zendawesome' ),
        'type' => Controls_Manager::WYSIWYG,
        'default' => __( 'Content', 'elementor-zendawesome' ),
      ]
    );
 
 
    $this->end_controls_section();
  }
 
  /**
   * Render the widget output on the frontend.
   *
   * Written in PHP and used to generate the final HTML.
   *
   * @since 1.1.0
   *
   * @access protected
   */
  protected function render() {
    $settings = $this->get_settings_for_display();
 
    $this->add_inline_editing_attributes( 'title', 'none' );
    $this->add_inline_editing_attributes( 'description', 'basic' );
    $this->add_inline_editing_attributes( 'content', 'advanced' );
    ?>
    <h2 <?php echo $this->get_render_attribute_string( 'title' ); ?>><?php echo $settings['title']; ?></h2>
    <div <?php echo $this->get_render_attribute_string( 'description' ); ?>><?php echo $settings['description']; ?></div>
    <div <?php echo $this->get_render_attribute_string( 'content' ); ?>><?php echo $settings['content']; ?></div>
    <?php
  }
 
  /**
   * Render the widget output in the editor.
   *
   * Written as a Backbone JavaScript template and used to generate the live preview.
   *
   * @since 1.1.0
   *
   * @access protected
   */
  protected function _content_template() {
    ?>
    <#
    view.addInlineEditingAttributes( 'title', 'none' );
    view.addInlineEditingAttributes( 'description', 'basic' );
    view.addInlineEditingAttributes( 'content', 'advanced' );
    #>
    <h2 {{{ view.getRenderAttributeString( 'title' ) }}}>{{{ settings.title }}}</h2>
    <div {{{ view.getRenderAttributeString( 'description' ) }}}>{{{ settings.description }}}</div>
    <div {{{ view.getRenderAttributeString( 'content' ) }}}>{{{ settings.content }}}</div>
    <?php
  }
}

Fichier assets/js/zendawesome.js

/*
 * File : assets/js/zendawesome.js
 */
( function( $ ) {
  /**
   * @param $scope The Widget wrapper element as a jQuery element
   * @param $ The jQuery alias
   */
  var WidgetZendawesomeHandler = function( $scope, $ ) {
    console.log( $scope );
  };
   
  // Make sure you run this code under Elementor.
  $( window ).on( 'elementor/frontend/init', function() {
    elementorFrontend.hooks.addAction( 'frontend/element_ready/zendawesome.default', WidgetZendawesomeHandler );
  } );
} )( jQuery );

Ajoutez les champs personnalisés à votre Widget Elementor

Elementor est super puissant vous permettant d’ajouter facilement des onglets personnalisés, des champs, des paramètres de style et même de la réactivité. Dans le code ci-dessus, le _register_controls est l’endroit où nous avons déjà ajouté quelques champs pour le titre, la description et le contenu, mais que faire si vous avez besoin de plus ? Jetez un coup d’œil aux exemples ci-dessous pour ajouter encore plus de génialitude à votre plugin Zendawesome.

Comment ajouter un onglet dans notre Widget ?

Vous pouvez ajouter/changer l’onglet de contenu et les options qui y apparaissent dans la barre latérale de l’éditeur Élémentor avec ce qui suit :

widgets/zendawesome.php – Dans la méthode _register_controls.

/**
 * File : widgets/zendawesome.php – Dans la méthode _register_controls.
 */

$this->start_controls_section(
  'section_content',
  [
    'label' => __( 'Content', 'elementor-zendawesome' ),
  ]
);
 
/* Add the options you'd like to show in this tab here */
 
$this->end_controls_section();

Comment changer le style des onglets dans Elementor ?

Vous pouvez ajouter/changer l’onglet Style et les options qui y apparaissent dans la barre latérale de l’éditeur Elémentor avec ce qui suit :

widgets/zendawesome.php – Dans la méthode _register_controls.

$this->start_controls_section(
  'style_section',
  [
    'label' => __( 'Style Section', 'elementor-zendawesome' ),
    'tab' => \Elementor\Controls_Manager::TAB_STYLE,
  ]
);
 
/* Add the options you'd like to show in this tab here */
 
$this->end_controls_section();

Comment ajouter un champ image personnalisé dans Elementor ?

La possibilité d’ajouter ou de modifier des images est cruciale pour tout bon thème WordPress, voici comment ajouter un champ image personnalisé dans un widget Elementor avec Controls_Manager::MEDIA :

widgets/zendawesome.php – Dans la méthode _register_controls.

$this->add_control(
      'mask_image',
      [
        'label' => __( 'Mask Image', 'elementor-zendawesome' ),
        'type' => Controls_Manager::MEDIA,
        'default' => [
          'url' => Utils::get_placeholder_image_src(),
        ]
      ]
    );

Comment ajouter une liste déroulante à Elementor ?

Et si nous voulions permettre à l’utilisateur de sélectionner l’élément HTML pour le titre, c’est aussi un jeu d’enfant avec Controls_Manager::SELECT :

widgets/zendawesome.php – En haut du fichier où se trouvent les instructions use.

use Elementor\Utils;

widgets/zendawesome.php – Dans la méthode _register_controls.

$this->add_control(
  'mask_image',
  [
    'label' => __( 'Mask Image', 'elementor-zendawesome' ),
    'type' => Controls_Manager::MEDIA,
    'default' => [
      'url' => Utils::get_placeholder_image_src(),
    ]
  ]
);

Comment créer un groupe de bouton dans Elementor ?

Pourquoi ne pas ajouter des options d’alignement en utilisant un groupe de boutons, facile avec Controls_Manager::CHOOSE :

widgets/zendawesome.php – Dans la méthode _register_controls.

$this->add_control(
  'text_align',
  [
    'label' => __( 'Alignment', 'elementor-zendawesome' ),
    'type' => \Elementor\Controls_Manager::CHOOSE,
    'options' => [
      'left' => [
        'title' => __( 'Left', 'elementor-zendawesome' ),
        'icon' => 'fa fa-align-left',
      ],
      'center' => [
        'title' => __( 'Center', 'elementor-zendawesome' ),
        'icon' => 'fa fa-align-center',
      ],
      'right' => [
        'title' => __( 'Right', 'elementor-zendawesome' ),
        'icon' => 'fa fa-align-right',
      ],
    ],
    'default' => 'center',
    'toggle' => true,
  ]
);

Comment modifier les Options de typographie du widget Élémentor ?

Elementor est livré avec un puissant éditeur de typographie qui inclut des options réactives, voici comment l’ajouter avec Group_Control_Typography & Scheme_Typography::TYPOGRAPHY_1.

widgets/zendawesome.php – En haut du fichier où se trouvent les instructions use.

use Elementor\Group_Control_Typography;
use Elementor\Scheme_Typography;

widgets/zendawesome.php – Dans la méthode _register_controls.

$this->add_group_control(
  Group_Control_Typography::get_type(),
  [
    'name'     => 'content_typography',
    'label'    => __( 'Typography', 'elementor-zendawesome' ),
    'scheme'   => Scheme_Typography::TYPOGRAPHY_1,
    'selector' => '{{WRAPPER}} .elementor-zendawesome',
    'fields_options' => [
      'letter_spacing' => [
        'range' => [
          'min' => 0,
          'max' => 100
        ]
      ]
    ]
  ]
);

Conclusion

Comme vous pouvez le constater il est relativement simple de créer son propre widget pour Elementor; la seule limitation c’est votre imagination ! Vous pouvez d’ailleurs créer un Widget qui ira chercher des infos en base de données en modifiant la query de WordPress

Comme toujours, vous avez le choix de me laisser un commentaire si l’envie vous en prend (ou pas 🙂 )


siddhy

Développeur web full stack depuis une 15aine d'année dans une agence web du sud de la France et Geek depuis toujours, l'apprentissage et le partage font parti intégrante de ma philosophie au même titre que l'évolution personnelle et la sagesse bouddhiste.

0 commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *