Custom Elementor widget development – step by step and easy (part 1)

Watch this easy, and step-by-step video to learn how to build custom Elementor widget – which is a very trendy topic in 2022.

In this tutorial, we will learn, how to create a custom Elementor widget. In real life project, you want to create a layout or block, but what, if you can’t achieve this with the available widgets in Elementor Free or Pro version! So, Knowledge of creating Elementor custom widgets will help you overcome this situation.

Let’s watch this video or read this tutorial, and I will show you exactly how. Trust me, it is very easy.

Custom Elementor widget development

I am creating 2 separate videos for this.

In this first part, I will create a very basic Elementor widget – a Card like this, with a Title and Description field.

Very basic Elementor custom widget
Very basic Elementor custom widget

And, in the second part, I will apply some advanced features to this custom Card widget. For example, some extra control, typography, and styling like background, font size color control, etc.

Some control you can define when you create custom Elementor widget from scratch
Some control you can define when you create custom Elementor widget from scratch

Install Elementor

Okay, first thing first. We need to install Elementor. You could skip this part if you already did. So, let’s install the Elementor plugin from the dashboard. From the WordPress dashboard left panel, we click Plugin->Add new->Search->Install and finally activate.

Install the Elementor plugin during this Elementor custom widget development

Now, let’s create our first Elementor page. We click, Pages->Add new, name it “Custom Widget” and now, click “Edit with Elementor”. Here you see, all the widgets and our new custom widget will be listed here.

Edit with Elementor button

Let’s get back to the actual part.

I have created and tested the widget already, so I am going to copy and explain, so it saves time.

So, in the first part, I am considering you have very basic PHP knowledge.

We are going to create a very basic Plugin for this, which will have only 2 PHP files. 1 – the plugin main file and 2 – the widget file within the “widgets” folder.

The reason, I am making this custom widget using a Plugin is because this way you can install it on any WordPress site and create as many custom Elementor widgets as you want.

If you don’t know much about WordPress plugins, don’t worry. This plugin itself has a very basic few lines. You will still understand, even you have zero knowledge of creating a WordPress plugin.

WordPress Elementor widgets plugin

Let’s go to our WordPress Directory “wp-content/plugins” and create our plugin folder. I name it “essential-elementor-widgets”.

Inside the folder, let’s create our plugin main PHP file “essential-elementor-widgets.php”.

Inside this, let’s put the plugin declaration so WordPress can recognize this plugin.

<?php
/**
 * Plugin Name: Essential Elementor Widgets
 * Description: Elementor custom widgets from Eessential Web Apps.
 * Plugin URI:  https://essentialwebapps.com/
 * Version:     1.0.0
 * Author:      Essential Web Apps
 * Author URI:  https://essentialwebapps.com/
 * Text Domain: essential-elementor-widget
 *
 * Elementor tested up to: 3.5.0
 * Elementor Pro tested up to: 3.5.0
 */

So here, all the basic things. Plugin name, Description, etc. If you want to know more about the WordPress plugins, then follow this link.

So now, in the dashboard, if you go to Plugins, you see, our plugin is here.

custom WordPress Elementor widgets plugin
We made a custom WordPress Elementor widgets plugin

Cool, right. We just created a plugin. Now it is time to write our code.

First, I am applying a very basic check, so that, no one access the plugin directly, it is for security.

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

Now, moving to the main things.

We will now register our custom Elementor widget. I am going to follow this documentation from the Elementor website. I put the link in the description.

So let’s put this.

function register_essential_custom_widgets( $widgets_manager ) {

    require_once( __DIR__ . '/widgets/card-widget.php' );  // include the widget file

    $widgets_manager->register( new \Essential_Elementor_Card_Widget() );  // register the widget

}
add_action( 'elementor/widgets/register', 'register_essential_custom_widgets' );

So, we wrote a function “register_essential_custom_widgets” and in this function, with this line, we include a widget.

require_once( __DIR__ . '/widgets/card-widget.php' );  // include the widget file

We will create this widget file “card-widget.php” soon.

Then with the following line, we register the Elementor widget.

$widgets_manager->register( new \Essential_Elementor_Card_Widget() );  // register the widget

Here, in this class “Essential_Elementor_Card_Widget”, we will write this class inside the widget file “card-widget.php” soon.

Now, we add an action to hook our code.

add_action( 'elementor/widgets/register', 'register_essential_custom_widgets' );

So, what is this action hook? I just wrote a simple explanation for you.

WordPress action explanation:

Actions are a big feature in WordPress that makes it easy to customize.

An action is a piece of code that we can use in WordPress to add new features without editing the core files.

For developers, Elementor also provides many predefined actions to add our own code at specific points of the Elementor.

These are called hooks, kind of we are attaching our own code with a hook to those specific points.

So, in this example, here, we are using the Elementor action hook “elementor/widgets/register” to attach our extra widget.

I will create a separate video on Action Hook, so, please subscribe to this Youtube Channel to get notified.

So, in short, with this function “register_essential_custom_widgets“, we are adding an extra widget using the Elementor action hook “elementor/widgets/register“. I hope you get it.

So, we have achieved a milestone. Our plugin file has been created and we have included and registered our new Card widget.

Elementor custom widget plugin full code

Now the plugin main file’s “essential-elementor-widget.php” complete codes are

<?php

/**
 * Plugin Name: Essential Elementor Widgets
 * Description: Elementor custom widgets from Eessential Web Apps.
 * Plugin URI:  https://essentialwebapps.com/
 * Version:     1.0.0
 * Author:      Essential Web Apps
 * Author URI:  https://essentialwebapps.com/
 * Text Domain: essential-elementor-widget
 *
 * Elementor tested up to: 3.5.0
 * Elementor Pro tested up to: 3.5.0
 */

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

/**
 * Register Widgets.
 *
 * Include widget file and register widget class.
 *
 * @since 1.0.0
 * @param \Elementor\Widgets_Manager $widgets_manager Elementor widgets manager.
 * @return void
 */
function register_essential_custom_widgets( $widgets_manager ) {

    require_once( __DIR__ . '/widgets/card-widget.php' );  // include the widget file

    $widgets_manager->register( new \Essential_Elementor_Card_Widget() );  // register the widget

}
add_action( 'elementor/widgets/register', 'register_essential_custom_widgets' );

Build custom Elementor widget

Let’s now create our Elementor widget.

Let’s create the folder “widgets” and then inside this, create the widget file we have included, that is “card-widget.php”.

We are creating the widget file inside the “widgets” folder because we wrote this /widgets/card-widget.php in the Plugin main file “essential-elementor-widget.php“.

Now start writing our widget code inside the file.

First, we will write, the very basic check for security, so no one can access the file directly.

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

Next, we will write our widget class.

class Essential_Elementor_Card_Widget extends \Elementor\Widget_Base { 
  // our widget code geos here
}

So, this class “Essential_Elementor_Card_Widget” must be the same as we register this widget with the same name in the plugin main file “essential-elementor-widget.php.

All widget functions for Elementor custom widget

Now, inside the class, we write this.

public function get_name() {
	return 'card';
}

This “get_name()” name function, returns the widget machine name, in this case, it is “card”, you can name it anything, but the best practice is to write something human-understandable.

Then move to the next function, we write this.

public function get_title() {
	return esc_html__( 'Essenial Card', 'essential-elementor-widget' );
}

Here this “get_title()” function, returns the Widget Human Readable name, in this case, I name it “Essential Card” which you will see in the Elementor dashboard.

And here, the “essential-elementor-widget” is the plugin Text Domain we wrote in the plugin file for translation purposes, so you can translate your plugin to another language.

Move to the next function “get_icon()”.


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

Which returns, the icon of the widget, which shows in the Elementor dashboard in the widget.

On the Elementor website, you see, you have the full list of icons you can call.

Next, write the function “get_custom_help_url()”.

public function get_custom_help_url() {
	return 'https://essentialwebapps.com/category/elementor-tutorial/';
}

Which returns, the help link in the widget, if you want to direct your user to a specific link of the documentation.

Next with the “get_categories()” function, we can put the widget in a specific category.


public function get_categories() {
	return [ 'general' ];
}

You see it in the dashboard. We put it under the general category. It is possible you can create a custom category and put it under this.

I will probably create an Elementor series where I will cover these. Please, hit the subscribe button for notification in the YouTube video.

Then the function, “get_keywords()”.


public function get_keywords() {
	return [ 'card', 'service', 'highlight', 'essential' ];
}

With this function, we can write our keywords, so that the widget can be found in the dashboard. For, example, if we search this widget in the dashboard, with any keyword (card), we have written here, will show the widget to select it.

We are halfway to this tutorial, and I am requesting to Share this article on social media hit the like icon below the video, so it reaches more audiences.

Control function for Elementor custom widget

Okay, so, now the most interesting part, where we will start coding our widget fields.

So, we will write the protected function “register_controls()”.

protected function register_controls() { 
	// our control function code goes here.
}

On the Elementor website, you will find all the controls, like text fields, text area fields, etc. you can declare.

Within this function, we will start the control section by writing this.

$this->start_controls_section(
	'content_section',
	[
	'label' => esc_html__( 'Content', 'essential-elementor-widget' ),
	'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
	]
);

Here, this parameter “content_section”, is the unique id, the machine name of the section, and in the “label” key, this “Content” is the name of our section.

And, in the “tab” field, with the control “TAB_CONTENT”, we are saying this section should go under the “Content” tab.

Elementor widget content section under content tab when it is final
Elementor widget content section under content tab when it is final

Now, we will declare a “text field” for our Card widget title by adding a “TEXT” control.

$this->add_control(
	'card_title',
	[
	'label' => esc_html__( 'Card title', 'essential-elementor-widget' ),
	'type' => \Elementor\Controls_Manager::TEXT,
	'label_block' => true,
	'placeholder' => esc_html__( 'Your card title here', 'essential-elementor-widget' ),
	]
);

So, here in this control,

  1. The parameter “card_title”, is the machine name
  2. In the array, with the “label” key, we put the Human readable name of the field “Card Title”.
  3.  with “type” key, we declare the input filed type as text field by “TEXT” control.
  4. label_block” as true, we are saying, the field should appear as a block in the admin side.
  5. With the “placeholder”, you know what it means. It shows the default place holder text, inside the field in the dashboard.

So, we are done with the title field, cool, right.

Now, we will declare our Card description field with the Elementor control “TEXTAREA”.

$this->add_control(
	'card_description',
	[
	'label' => esc_html__( 'Card Description', 'essential-elementor-widget' ),
	'type' => \Elementor\Controls_Manager::TEXTAREA,
	'label_block'   => true,
	'placeholder' => esc_html__( 'Your card description here', 'essential-elementor-widget' ),
	]
);

It has a similar code, to our text field. So, I hope I don’t need to explain this again.

Okay, so are done with the two fields.

Now, we need to end the control section we declared at the beginning here by this line.

$this->end_controls_section();

So, we are done with the “register_controls” function.

Render function for custom Elementor widget

Now, it is time to write the code which will generate the output of the widget.

We will write the “render()” function for this. The render the widget output in the front end.

protected function render() {

        // get our input from the widget settings.
        $settings = $this->get_settings_for_display();
	
	// get the individual values of the input
	$card_title = $settings['card_title'];
	$card_description = $settings['card_description'];

	?>

        <!-- Start rendering the output -->
        <div class="card">
            <h3 class="card_title"><?php echo $card_title;  ?></h3>
            <p class= "card__description"><?php echo $card_description;  ?></p>
        </div>
        <!-- End rendering the output -->

        <?php

}

Here, in the render function, with “$this->get_settings_for_display();

we get the input field values which we will hold with the variable “$settings” as an Array.

So, from this Array, we access the Title field value with this “$settings['card_title'];

And the Description field value from this “$settings['card_description'];

So, now we hold the values of our fields with the variables “$card_title” and “$card_description”.

Now, it is time to echo these variables with some HTML to see the output. So, we write this.

<div class="card">
   <h3 class="card_title"><?php echo $card_title;  ?></h3>
   <p class= "card__description"><?php echo $card_description;  ?></p>
</div>

Now, we have declared a DIV, then echoing the title with heading tag H3, and then with a paragraph tag P, we are echoing the description.

Elementor custom widget file full code

Altogether, the final codes of the card-widget.php are as follows.

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


/**
 * Essential Elementor Card Widget.
 *
 * Elementor widget that inserts a card with title and description.
 *
 * @since 1.0.0
 */
class Essential_Elementor_Card_Widget extends \Elementor\Widget_Base { 
  

  	/**
	 * Get widget name.
	 *
	 * Retrieve Card widget name.
	 *
	 * @since 1.0.0
	 * @access public
	 * @return string Widget name.
	 */
	public function get_name() {
		return 'card';
	}


	/**
	 * Get widget title.
	 *
	 * Retrieve Card widget title.
	 *
	 * @since 1.0.0
	 * @access public
	 * @return string Widget title.
	 */
	public function get_title() {
		return esc_html__( 'Essenial Card', 'essential-elementor-widget' );
	}

	/**
	 * Get widget icon.
	 *
	 * Retrieve Card widget icon.
	 *
	 * @since 1.0.0
	 * @access public
	 * @return string Widget icon.
	 */
	public function get_icon() {
		return 'eicon-header';
	}


	/**
	 * Get custom help URL.
	 *
	 * Retrieve a URL where the user can get more information about the widget.
	 *
	 * @since 1.0.0
	 * @access public
	 * @return string Widget help URL.
	 */
	public function get_custom_help_url() {
		return 'https://essentialwebapps.com/category/elementor-tutorial/';
	}

	/**
	 * Get widget categories.
	 *
	 * Retrieve the list of categories the Card widget belongs to.
	 *
	 * @since 1.0.0
	 * @access public
	 * @return array Widget categories.
	 */
	public function get_categories() {
		return [ 'general' ];
	}

	/**
	 * Get widget keywords.
	 *
	 * Retrieve the list of keywords the Card widget belongs to.
	 *
	 * @since 1.0.0
	 * @access public
	 * @return array Widget keywords.
	 */
	public function get_keywords() {
		return [ 'card', 'service', 'highlight', 'essential' ];
	}



	/**
	 * Register Card widget controls.
	 *
	 * Add input fields to allow the user to customize the widget settings.
	 *
	 * @since 1.0.0
	 * @access protected
	 */
	protected function register_controls() { 
		// our control function code goes here.

		$this->start_controls_section(
			'content_section',
			[
				'label' => esc_html__( 'Content', 'essential-elementor-widget' ),
				'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
			]
		);

		$this->add_control(
			'card_title',
			[
				'label' => esc_html__( 'Card title', 'essential-elementor-widget' ),
				'type' => \Elementor\Controls_Manager::TEXT,
				'label_block' => true,
				'placeholder' => esc_html__( 'Your card title here', 'essential-elementor-widget' ),
			]
		);


		$this->add_control(
			'card_description',
			[
				'label' => esc_html__( 'Card Description', 'essential-elementor-widget' ),
				'type' => \Elementor\Controls_Manager::TEXTAREA,
				'label_block'   => true,
				'placeholder' => esc_html__( 'Your card description here', 'essential-elementor-widget' ),
			]
		);	

		$this->end_controls_section();

	}

	/**
	 * Render Card widget output on the frontend.
	 *
	 * Written in PHP and used to generate the final HTML.
	 *
	 * @since 1.0.0
	 * @access protected
	 */
	protected function render() { 

		// get our input from the widget settings.
		$settings = $this->get_settings_for_display();

		// get the individual values of the input
		$card_title = $settings['card_title'];
		$card_description = $settings['card_description'];

		?>

        <!-- Start rendering the output -->
        <div class="card">
            <h3 class="card_title"><?php echo $card_title;  ?></h3>
            <p class= "card__description"><?php echo $card_description;  ?></p>
        </div>
        <!-- End rendering the output -->

        <?php
		

	}						


}

Here is our output.

Final output of this Elementor widget
Final output of this Elementor widget

Isn’t it simple to create a custom Elementor widget? I believe your answer is yes. Wow, we just learned, how to create a custom Elementor widget.

In the next video, I will extend this widget by applying some Typography and styling to it. Subscribe to the YouTube channel, and please click the bell icon for notification.

Also, please check these some awesome WordPress themes you may be like for your next WordPress website project. I will see you in the next video. Till then take care :).

About the Author

Jamal is a WordPress Developer having more than 10 years of experience and is based in Helsinki, Finland. He is doing his 9-5 Developer job but, in his free time, he loves to create tutorials and connect with people.