Extend Elementor like a pro: Creating a new extension in Elementor

Creating a New Extension Featured Image

Elementor is a powerful drag and drop page builder that allows us to create pages conveniently. One of Elementor’s greatest features is extendibility. With this feature, we can build custom widgets/controls via creating a new extension in Elementor.

This extension implements object-oriented programming in which a main class and extra classes for smaller parts like custom Elementor Widgets or any other components are used.

Plugin Structure

The main plugin should have basic information about the extensions, to check basic requirements and to load the required files to activate the plugin functionality. In the following sections, we’ll take a deep dive into each part of the plugin.

Defining Variable

Variables are used to store information to be referenced and manipulated in a computer program.

In the main class, we must define three constants like:

  • VERSION: store the version of our plugin.
  • MINIMUM_ELEMENTOR_VERSION: store the essential version of Elementor.
  • MINIMUM_PHP_VERSION: store the PHP version used in the plugin.
const VERSION;
const MINIMUM_ELEMENTOR_VERSION;
const MINIMUM_PHP_VERSION;

Single Instance

The singleton pattern is used to restrict the instantiation of a class to a single object, which can be useful when only one object is required across the system.

When creating a new extension in Elementor, we can only have one instance of the main class. To do this, we use a singleton pattern. In this pattern, we must define a private static variable and public static function.

private static $_instance = null;

	public static function instance() {
            //check $_instance is null or not
		if ( is_null( self::$_instance ) ) {
			self::$_instance = new self();
		}
		return self::$_instance;

	}

Constructor

The Constructor or magic function is a special type of function that is automatically executed after a class is created or instantiated. Usually, the constructor starts with two underscore characters.

In the main class, the role of the constructor is to load localization functionality and initiate the plugin.

public function __construct() {

		add_action( 'init', [ $this, 'i18n' ] );
		add_action( 'plugins_loaded', [ $this, 'init' ] );

	}
public function i18n() {
		load_plugin_textdomain( 'our-plugin-name' );
	}
public function init() {
		// Plugin logic here...
	}

Check if Elementor is Installed

As the plugin extends Elementor functionality, you should first check whether Elementor is installed and activated before the main class loads.

If Elementor is activated, the main class will load. If it’s not activated, an admin notice will be displayed and the functionality won’t continue loading. This check must be done in the initialization stage of the main class.

public function init() {

		// Check if Elementor installed and activated
		if ( ! did_action( 'elementor/loaded' ) ) {
			add_action( 'admin_notices', [ $this, 'admin_notice_missing_main_plugin' ] );
			return;
		}

	}

	public function admin_notice_missing_main_plugin() {

		if ( isset( $_GET['activate'] ) ) unset( $_GET['activate'] );

		$message = sprintf(
			/* translators: 1: Our plugin name 2: Elementor */
			esc_html__( '"%1$s" requires "%2$s" to be installed and activated.', 'our-plugin-name' ),
			'<strong>' . esc_html__( 'Elementor our-plugin-name', 'our-plugin-name' ) . '</strong>',
			'<strong>' . esc_html__( 'Elementor', 'our-plugin-name' ) . '</strong>'
		);

		printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );

	}

Check the Version of Elementor

After checking whether or not Elementor is installed, we must check the Elementor version for backward compatibility with older Elementor versions. If the defined minimum version of our plugin is not compatible with the installed version of Elementor, then the admin message will be displayed, and functionality will not be able to load.
This check is done in the initialisation stage of the main class.

const MINIMUM_ELEMENTOR_VERSION = '2.5.11';

	public function init() {

		// 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;
		}

	}

	public function admin_notice_minimum_elementor_version() {

		if ( isset( $_GET['activate'] ) ) unset( $_GET['activate'] );

		$message = sprintf(
			/* translators: 1: Our plugin name 2: Elementor 3: Required Elementor version */
			esc_html__( '"%1$s" requires "%2$s" version %3$s or greater.', 'our-plugin-name' ),
			'<strong>' . esc_html__( 'Elementor our-plugin-name', 'our-plugin-name' ) . '</strong>',
			'<strong>' . esc_html__( 'Elementor', 'our-plugin-name' ) . '</strong>',
			 self::MINIMUM_ELEMENTOR_VERSION
		);

		printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );

	}

Check for the PHP Version

Finally, we must check our extension’s minimum PHP version, which . must be newer than the PHP version of the Elementor plugin. If there’s an older version, then the admin message will be displayed, and the functionality won’t load.

const MINIMUM_PHP_VERSION = '7.0';

	public function init() {

		// 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;
		}

	}

	public function admin_notice_minimum_php_version() {

		if ( isset( $_GET['activate'] ) ) unset( $_GET['activate'] );

		$message = sprintf(
			/* translators: 1: Our plugin name 2: PHP 3: Required PHP version */
			esc_html__( '"%1$s" requires "%2$s" version %3$s or greater.', 'our-plugin-name' ),
			'<strong>' . esc_html__( 'Elementor our-plugin-name', 'extension-name' ) . '</strong>',
			'<strong>' . esc_html__( 'PHP', 'our-plugin-name' ) . '</strong>',
			 self::MINIMUM_PHP_VERSION
		);

		printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );

	}

Including Essential Files to Correctly Create a New Extension

After completing all checks, the extension must load essential files like widgets and controls in order for it to run correctly.

public function init() {

		// Add Plugin actions
		add_action( 'elementor/widgets/widgets_registered', [ $this, 'init_widgets' ] );
		add_action( 'elementor/controls/controls_registered', [ $this, 'init_controls' ] );
	}

	public function init_widgets() {

		// Include Widget files
		require_once( __DIR__ . '/widgets/our-plugin-name-widget.php' );

		// Register widget
		\Elementor\Plugin::instance()->widgets_manager->register_widget_type( new \Elementor_extension_Widget() );

	}

	public function init_controls() {

		// Include Control files
		require_once( __DIR__ . '/controls/our-plugin-name-control.php' );

		// Register control
		\Elementor\Plugin::$instance->controls_manager->register_control( 'control-type-', new \extension_Control() );

	}

Workflow Diagram

Create a New Extension - Workflow Diagram

In the end, if we want to create our extension named Spicy, we must have the following code in its entirety.

<?php
 /**
 * Plugin Name: Spicy Extension
 * Description: Custom Elementor extension.
 * Plugin URI:  https://spicy.test/
 * Version:     1.0.0
 * Author:      Spicy
 * Author URI:  https://spicy.test/
 * Text Domain: spicy-extension
 */

	if ( ! defined( 'ABSPATH' ) ) {
		exit; // Exit if accessed directly.
	}

	/**
	 * Main Spicy Extension Class
	 *
	 * The main class that initiates and runs the plugin.
	 *
	 * @since 1.0.0
	 */
	final class Spicy_Extension {

		/**
		 * 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.5.11';

		/**
		 * Minimum PHP Version
		 *
		 * @since 1.0.0
		 *
		 * @var string Minimum PHP version required to run the plugin.
		*/
		const MINIMUM_PHP_VERSION = '6.0';

		/**
		 * Instance
		 *
		 * @since 1.0.0
		 *
		 * @access private
		 * @static
		 *
		 * @var Spicy_Extension 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.0.0
		 *
		 * @access public
		 * @static
		 *
		 * @return Spicy_Extension An instance of the class.
		 */
		public static function instance() {

			if ( is_null( self::$_instance ) ) {
				self::$_instance = new self();
			}

		 	return self::$_instance;
		}

		/**
		 * Constructor
		 *
		 * @since 1.0.0
		 *
		 * @access public
		 */
		
		public function __construct() {	
			add_action( 'init', [ $this, 'i18n' ] );
			add_action( 'plugins_loaded', [ $this, 'init' ] );
		}

		/**
		 * Load Textdomain
		 *
		 * Load plugin localization files.
		 *
		 * Fired by `init` action hook.
		 *
		 * @since 1.0.0
		 *
		 * @access public
		 */
		public function i18n(){}

		/**
		 * Initialize the plugin
		 *
		 * Load the plugin only after Elementor (and other plugins) are loaded.
		 * Checks for basic plugin requirements, if one check fail don't continue,
		 * if all check have passed load the files required to run the plugin.
		 *
		 * Fired by `plugins_loaded` action hook.
		 *
		 * @since 1.0.0
		 *
		 * @access public
		 */
		public function init() {

			// Check if Elementor installed and activated
			if ( ! did_action( 'elementor/loaded' ) ) {
				add_action( 'admin_notices', [ $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', [ $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', [ $this, 'admin_notice_minimum_php_version' ] );
				return;
			}

			// Add Plugin actions
			add_action( 'elementor/widgets/widgets_registered', [ $this, 'init_widgets' ] );
			add_action( 'elementor/controls/controls_registered', [ $this, 'init_controls' ] );
			
			// Register Widget Styles
			add_action( 'elementor/frontend/after_enqueue_styles', [ $this, 'widget_styles' ] );

		}

		public function widget_styles() {
			//For Example
			//wp_enqueue_style( 'spicyPluginStylesheet', plugins_url( '/css/gallery.css', __FILE__ ) );
		}

		/**
		 * 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.', 'Spicy-extension' ),
				'<strong>' . esc_html__( 'Elementor Spicy Extension', 'Spicy-extension' ) . '</strong>',
				'<strong>' . esc_html__( 'Elementor', 'Spicy-extension' ) . '</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.', 'Spicy-extension' ),
				'<strong>' . esc_html__( 'Elementor Spicy Extension', 'Spicy-extension' ) . '</strong>',
				'<strong>' . esc_html__( 'Elementor', 'Spicy-extension' ) . '</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.', 'Spicy-extension' ),
				'<strong>' . esc_html__( 'Elementor Spicy Extension', 'Spicy-extension' ) . '</strong>',
				'<strong>' . esc_html__( 'PHP', 'Spicy-extension' ) . '</strong>',
				self::MINIMUM_PHP_VERSION
			);

			printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );

		}

		/**
		 * Init Widgets
		 *
		 * Include widgets files and register them
		 *
		 * @since 1.0.0
		 *
		 * @access public
		 */
		public function init_widgets() {
			 // For Example
			// Include Widget files
			//require_once( __DIR__ . '/widgets/gallery.php' );

			// Register widget
			//\Elementor\Plugin::instance()->widgets_manager->register_widget_type( new \spicy_oEmbed_Widget() );
			//\Elementor\Plugin::instance()->widgets_manager->register_widget_type( new \spicy_gallery_Widget() );

		}

		/*
		 * Init Controls
		 *
		 * Include controls files and register them
		 *
		 * @since 1.0.0				
		 *
		 * @access public
		*/
		public function init_controls() {
			//For example
			
			//Include Control files
			//require_once( __DIR__ . '/controls/multi-unit.php' );

			// Register control
		    //\Elementor\Plugin::$instance->controls_manager->register_control( 'spicy-multi-unit-control', new spicy_multi_unit());

		}

    }

spicy_Extension::instance();

Also, you can download the entire code by clicking on this link.

Conclusion

In this article, we went into depth to illustrate the basic structure of the plugin that extends the functionality of Elementor. Also, we explained each essential part of the plugin code like Variable, Single Instance, Constructor, Checking steps and Include files. Finally, we included the entire code for the Spicy plugin.

We’d love to hear from you! Feel free to drop us a comment to share your experiences and ideas.

Some Handy Elementor Plugins for Jupiter X

Elementor Plugins for Jupiter X featured image

Elementor page builder enables you to deliver high-end page designs with advanced capabilities, never before seen on WordPress. The standard and extendable nature of this plugin allow developers to create plugins to add new features to it.

Jupiter X theme is using Elementor as its default page builder. It’s also coded with standard practices so the Elementor community plugins are compatible with the theme. In this article, let’s cover some handy Elementor plugins for Jupiter X theme. The plugins are divided into two main categories:

  • Adding new widgets to Elementor
  • Extending functionalities of Elementor

Note: The compatibility of the plugins with Jupiter X theme have been tested at the time of writing this article.

HT Mega – Ultimate Addons for Elementor Page Builder

HT Mega extends Elementor with 80+ elements and 360 blocks with various styles. The live demo can show you the real usage of the elements.

Features:

  • Ability to enable/disable elements to improve performance
  • Unlimited Color and Typography options
  • Fully responsive and mobile ready
  • Cross Browser Compatible

Available Elements:

  • Team member
  • User login form
  • User register form
  • Litebox
  • Instagram
  • Twitter feed
  • Image magnifier
  • Etc.

Download here.

Premium Addons for Elementor

Premium Elementor add-ons and widgets with numerous customization options are available to extend the Elementor Page Builder capabilities and help you build impressive websites with no coding required. The live demo can show you the real usage of the elements.

Features:

  • 22+ Fully Customizable Elementor add-on widgets
  • Options panel for enabling desired widgets only for faster performance
  • Fully Responsive and Cross Browser Compatible

Available Elements:

  • Blog
  • Dual heading
  • Fancy text
  • Image separator
  • Counter
  • Modal box
  • Image button
  • And more.

Download here.

Image Hover Effects Add-on for Elementor

You can add 40+ Image hover effects with title and descriptions in a simple way, using this WordPress plugin image hover effects add-on for Elementor. The live demo can show you the real usage of the elements.

Features:

  • Easy to customize options
  • 40+ Image Hover Effects
  • Circle and Square border both come with all effects
  • Center the text horizontally
  • Control the spaces between elements

Effects:

  • Fade
  • Slide
  • Reveal
  • Push
  • Hinge
  • Flip
  • Shutter
  • Fold
  • Zoom
  • Blur

Download here.

Contact Form 7 Widget For Elementor Page Builder

This plugin adds a new element to Elementor Page Builder which helps you to easily drag and drop contact form 7 forms from a drop-down list. No need to go into your Contact Form 7 to copy the shortcode and add it to your Elementor widget anymore — simply drag and drop!

Features:

  • Add CSS directly from Elementor live preview to your contact form 7
  • Add any WordPress page as a thank you page directly from the Elementor edit screen when you add the VOID Contact Form 7 widget
  • Use single Contact Form 7 with different Style and redirect rule

Download here.

Toolbar Extras for Elementor – WordPress Admin Bar Enhanced

This plugin is a huge time saver. It enables you to have quick access to your site building resources. Using the Toolbar Extras plugin, you can add useful links to the top toolbar of your admin page and access links quickly to reduce scrolling and save time. Furthermore, with this plugin, you can access links when from the frontend.

Features:

Page Builder links: Elementor & Elementor Pro.
Links for Elementor Add-On Plugins.
Enhances the New Content section (under + New) with more links.
Support for creating an internal new Menu for Admins which hooks into the Toolbar.
Fully internationalized and translatable also for RTL language.

The main item has useful links.

This plugin enhances + New

Download here.

Custom Fonts

One of the important factors in typography is a good font. If you need to use your custom font in your website, you can use the Custom Fonts plugin. This plugin allows you to add a custom web font to Elementor font library.

Adding a Custom Font

1. To add your custom font, go to Appearance > Custom Fonts then upload your fonts. We downloaded Sonika and converted it to a web font using the Web font generator tool.

2. Use your custom font like other fonts. It’s added at the top of Fonts under Custom group.

Download here.

Custom Icons for Elementor

Elementor comes with Font Awesome icons by default and there’s no way to upload custom icons. But the Custom Icons for Elementor plugin enables you to add your custom icons to the built-in Elementor icon controls and elements.

How to Add Custom Icons

1. Select some icons in Fontello website, then download them.

2. Upload the downloaded zip file in Elementor > Custom Icons.

3. Use your custom icons.

Download here.

Elementor Blocks for Gutenberg

As you may know, Gutenberg is the default WordPress editor. But Elementor Blocks for Gutenberg allows you to easily insert any Elementor template into Gutenberg with just one click.  By using this plugin, you can benefit from both page builder features.

Add an Elementor Template in Gutenberg

1. Edit a page. Add Elementor Library block in the page, then select your template.  

2. You will see your Elementor template inside your Gutenberg page.

Download here.

Elementor Element Condition

This plugin gives you the ability to add conditions to sections and widgets so they can be shown or hidden. At the moment, it only supports two simple variables and one operator.

  • This plugin adds Condition section for all widgets in Style tab.
  • The Digital Solutions section will be only visible to logged in users based on the following condition.

Download here.

Make Column Clickable Elementor

This plugin adds a very handy and simple feature to the Elementor column. It allows you to make the whole column clickable.

This plugin adds a Custom Link setting in Column > Layout tab.

Download here.

Visibility Logic for Elementor

Hide or show an Elementor widget based on the user’s role. Based on your visibility setting for each widget, you can restrict rendering elements from the front-end, meaning that you can hide or show any Elementor widget based on the user role (Subscriber, Author, Administrator, etc), whether the user is Logged in or not.

This plugin adds a Visibility control section for all widgets in the Advanced tab with the following settings.

  • Enable conditions
  • Visible for
  • Hidden for

Download here.

Elementor Plugins for Jupiter X will make your life easier!

In this article, we introduced some handy Elementor plugins for Jupiter X. Some plugins add widgets, while some extend the functionality of Elementor page builder.

There are also some other plugins in the WordPress Community that you can try. Feel free to share your favorite one with us in the comments section!