Documentation for creating Elementor widget is available at the link – https://developers.elementor.com/docs/widgets/
1. Create a new file class-elementor-widget.php and place it in a folder with your classes, for example – pluginname/inc/
2. In the main file of your template pluginname.php attach the file you created:
require plugin_dir_path(__FILE__) . 'inc/class-elementor-widget.php';
3. Add the code to class-elementor-widget.php:
<?php final class Elementor_myWidget_Extension { const VERSION = '1.0.0'; //widget version const MINIMUM_ELEMENTOR_VERSION = '2.0.0'; //minimum Elementor version to launch our widget const MINIMUM_PHP_VERSION = '7.4';//minimum PHP version to launch our widget private static $_instance = null; public static function instance() { if ( is_null( self::$_instance ) ) { self::$_instance = new self(); } return self::$_instance; } public function __construct() { add_action( 'plugins_loaded', [ $this, 'on_plugins_loaded' ] ); add_action('elementor/elements/categories_registered',[$this,'add_elemntor_widget_categories']); } public function i18n() { // load translation files load_plugin_textdomain( 'elementor-test-extension' ); } public function on_plugins_loaded() { //checks when loading the plugin if ( $this->is_compatible() ) { add_action( 'elementor/init', [ $this, 'init' ] ); } } public function is_compatible() { // Check if Elementor installed and activated if ( ! did_action( 'elementor/loaded' ) ) { add_action( 'admin_notices', [ $this, 'admin_notice_missing_main_plugin' ] ); return false; } // Check for required Elementor version if ( ! version_compare( ELEMENTOR_VERSION, self::MINIMUM_ELEMENTOR_VERSION, '>=' ) ) { add_action( 'admin_notices', [ $this, 'admin_notice_minimum_elementor_version' ] ); return false; } // Check for required PHP version if ( version_compare( PHP_VERSION, self::MINIMUM_PHP_VERSION, '<' ) ) { add_action( 'admin_notices', [ $this, 'admin_notice_minimum_php_version' ] ); return false; } return true; } public function init() { $this->i18n(); // Add Plugin actions add_action( 'elementor/widgets/widgets_registered', [ $this, 'init_widgets' ] ); } public function init_widgets() { // Include Widget files require_once( __DIR__ . '/elementor/post-widget.php' ); // Register our widget \Elementor\Plugin::instance()->widgets_manager->register_widget_type( new \Elementor_Posts_Widget() ); } 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-test-extension' ), '<strong>' . esc_html__( 'Elementor Test Extension', 'elementor-test-extension' ) . '</strong>', '<strong>' . esc_html__( 'Elementor', 'elementor-test-extension' ) . '</strong>' ); printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message ); } 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-test-extension' ), '<strong>' . esc_html__( 'Elementor aleProperty Extension', 'elementor-test-extension' ) . '</strong>', '<strong>' . esc_html__( 'Elementor', 'elementor-test-extension' ) . '</strong>', self::MINIMUM_ELEMENTOR_VERSION ); printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message ); } 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-test-extension' ), '<strong>' . esc_html__( 'Elementor Test Extension', 'elementor-test-extension' ) . '</strong>', '<strong>' . esc_html__( 'PHP', 'elementor-test-extension' ) . '</strong>', self::MINIMUM_PHP_VERSION ); printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message ); } function add_elemntor_widget_categories($elements_manager){ //register category for our widget $elements_manager->add_category( 'Ouput', array( 'title' => esc_html('Output widgets'), 'icon' => 'fa fa-bullhorn', ) ); } } Elementor_myWidget_Extension::instance(); ?>
4. In the folder inc create a new directory and name it elementor.
5. In the folder elementor add a new file and name it posts-widger.php. Add the code to the file:
<?php class Elementor_Posts_Widget extends \Elementor\Widget_Base { public function get_name() { // Widget id return 'postwidget'; } public function get_title() { return esc_html__( 'Post list', 'translatedomain' ); } public function get_icon() { // icon from https://fontawesome.com/ return 'fa fa-bars'; } public function get_categories() { // category return [ 'output' ]; } protected function _register_controls() { $this->start_controls_section( // open control section 'content_section', [ 'label' => esc_html__( 'Content', 'translatedomain' ), 'tab' => \Elementor\Controls_Manager::TAB_CONTENT, ] ); $this->add_control( 'count', [ 'label' => esc_html__( 'Posts Count', 'translatedomain' ), 'type' => \Elementor\Controls_Manager::TEXT, 'default' => 3, ] ); $this->add_control( 'type', [ 'label' => esc_html__( 'Type', 'translatedomain' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => '', 'options' => [ '' => 'Select', 'sale' => esc_html__( 'Film', 'translatedomain' ), 'rent' => esc_html__( 'Series', 'translatedomain' ), 'sold' => esc_html__( 'Thrailer', 'translatedomain' ), ], ] ); $this->end_controls_section(); // close control } protected function render() { $settings = $this->get_settings_for_display(); $args = array( 'post_type' => 'posts', 'posts_per_page' => $settings['count'], 'meta_query' => array('relation'=>'AND'), 'tax_query' => array('relation'=>'AND'), ); if(isset($settings['type']) && $settings['type'] != '' ){ array_push($args['meta_query'],array( 'key' => 'type', 'value' => esc_attr($settings['offer']), )); } $posts = new WP_Query($args); if ( $posts->have_posts() ) { echo '<div class="wrapper archive_property">'; while ( $posts->have_posts() ) { $properties->the_post(); <?php the_title(); ?> } echo '</div>'; } wp_reset_postdata(); } }
Congratulations, now you will find a new widget in the Elementor tab!