Using Existing Widgets
Elementor is one of the best page builders to design your website out there. If you’re just starting out with Elementor, spend some time getting familiar with it before going off and creating your own widgets.
As a general rule if there is an easy way to accomplish a task without creating a new widget then for goodness sakes, go with the easy option and use the default functionality. If that doesn’t work your next best bet would be to try and customize an existing widget using styles and scripts.
If you’ve exhausted the first two options and are ready to create an Elementor widget, we’ll walk you through how to go about doing it.
The principle reason you’d want to create a custom Elementor widget is that the functionality you want is not available in an existing widget. To figure whether this is true, take a look at the widgets available in the Elementor Elements sidebar. Also, spend some time looking for the functionality you want in existing plugins. If you cannot find the widget you need, it’s time to create a custom widget.
Creating Your Own Widget
Dev Environment
To make this post easy to understand, we’ve provided a github repo and development environment, so you can follow along: https://github.com/pajtai/elementor-widgets-tutorial
At Solid Digital when we develop WordPress websites, we use Vagrant boxes provisioned by Ansible for local development. In this way, once we have a local environment set up for a client, we can use the same Ansible provisioning roles to setup the clients staging and production environments. We have a custom box we use, but we wanted something easy to setup and public for this demo. We tried Local by Flywheel and VVV, but they both had setups with too many steps. After more research we settled on VCCW, since it can be incorporated into an existing repo. To get going to follow this post, simply clone the demo repo, run vagrant up, and open http://192.168.33.10/. You’ll have to make sure you have Vagrant installed, and note that Vagrant depends on Virtualbox:
git clone git@github.com:pajtai/elementor-widgets-tutorial.git
cd elementor-widgets-tutorial
vagrant up
bin/open
Let’s create a dropdown as a custom widget. A dropdown is a good example for a custom widget, since the HTML desired for a dropdown can be a highly personal choice, so it makes sense to customize it as a widget. We’ll also show you how to make the choices in the dropdown configurable.
Login to http://192.168.33.10/wp-admin/plugins.php using admin
:admin
, and activate the Elementor plugin. You can use bin/open
to quickly get to the wp-admin
page.
Getting Started
The first decision to make is whether to add the widget to a plugin or your current theme. In general putting the widget into a plugin allows you to reuse your widget later. It also allows you to separate your widget code, styling, and scripts from the theme. If you are creating a widget that only makes sense for your current project, then puting it in the theme might be a good idea.
In our case, we’ll create a plugin called elementor-dropdown
in wp-content/plugins/elementor-dropdown
.
In order to be able to concentrate on the items unique to an elementor plugin, we’re going to go with a very simple single file structure. In reality you will want to add all the standard goodies to your plugin. These would include thing like internationalization, verifying that Elementor is activated, verifying the PHP version, etc. In our case, this extra boiler plate would obscure the functionality we’re interested in.
We want to keep the plugin as simple as possible, but the Elementor namespace is not available until after Elementor is loaded. If you try to access the Widget_Base
class too early, you’ll get a Class 'Elementor\Widget_Base' not found.
error. So let’s move our class to a separate file and only load it after Elementor is loaded.
This issue is not documented on Elementor’s Widget Creation Page, so I had to do a little trial an error to find the correct action to hook into. plugins_loaded
still produces the error, but elementor/widgets/widgets_registered
seems to work:
widgets_manager->register_widget_type( $drop_down_widget );
});
Once the widgets_registered
action runs, we can register our own widget using Plugin::instance()->widgets_manager->register_widget_type
.
To create an Elementor widget, we’ll use an OOP approach, since Elementor has a base Class we can extend.
With the class, you can define a widgets name and title. The icon is the icon that will be shown in the left hand sidebar of the Elementor editor, and the category is the category or categories that will be shown under it in the left hand sidebar. The default categories are “basic,” “general,” and “wordpress.”
At this point you should activate the Elementor Dropdown plugin. Now you’ll be able to see it when you edit a post.
Controls
Next we want to add the value and name for each dropdown. Elementor calls the inputs an admin uses to customize a widget “controls.” So we want to register some controls. First we’ll register just enough controls for one option, then we’ll add the ability for the admin user to dynamically add, remove, and reorder the dropdown options.
Available controls are listed here. We’ll start by using two text controls to capture the value attribute and content of one element:
start_controls_section(
'content_section',
[
'label' => __( 'Options', self::$slug ),
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'widget_value',
[
'label' => __( 'value', self::$slug ),
'type' => \Elementor\Controls_Manager::TEXT,
'default' => __( 'value', self::$slug ),
'placeholder' => __( 'Value Attribute', self::$slug ),
]
);
$this->add_control(
'widget_contents',
[
'label' => __( 'contents', self::$slug ),
'type' => \Elementor\Controls_Manager::TEXT,
'default' => __( 'contents', self::$slug ),
'placeholder' => __( 'Option Contents', self::$slug ),
]
);
$this->end_controls_section();
}
Now when you add an Elementor Dropdownor click on an existing one, you’ll see an “Options” section in the left hand sidebar, and you’ll see textboxes to add a Value and Contents. With this code, Elementor will save updates to these values for you. You’ll notice that the values show up neither in the Elementor preview on the right or on the front end. We’ll get to that soon, but first let’s add the ability to add more than one option.
To add multiple options, we’ll use the repeater control. An example of the repeater control in the existing widgets is the Tabs Widget.
The concept of repeaters is a general and useful one. Repeaters allow you to reuse a set of items by creating and managing multiple copies of the set. Usual options for management of the repeated items are the ability to reorder them, add more sets, and delete sets. Another example of the usage of a repeater is in the popular Advanced Custom Fields Plugin.
To use an Elemntor repeater, we have to first define what one set looks like. Then we can allow that set to be repeated.
We can use the \Elementor\Repeater
class to define what we want to be able to repeat. Note that basically the only change is that we add the controls to the $repeater
instead of to the Widget instance:
add_control(
'option_value',
[
'label' => __( 'Option Value', self::$slug ),
'type' => \Elementor\Controls_Manager::TEXT,
'default' => __( "The Option's Value", self::$slug ),
'placeholder' => __( 'Value Attribute', self::$slug ),
]
);
$repeater->add_control(
'option_contents',
[
'label' => __( 'Option Contents', self::$slug ),
'type' => \Elementor\Controls_Manager::TEXT,
'default' => __( "The Option's Contents", self::$slug ),
'placeholder' => __( 'Option Contents', self::$slug ),
]
);
The above defines the tab_title
and tab_contents
as the set of items that we can repeat. To add the $repeater
to the widget we then do:
add_control(
'options_list',
[
'label' => __( 'Repeater List', self::$slug ),
'type' => \Elementor\Controls_Manager::REPEATER,
'fields' => $repeater->get_controls(),
'default' => [
[]
],
'title_field' => '{{{ option_contents }}}'
]
);
The default
field above means that when we add a new Dropdown, it will be populated with one option using the default values defined on a single option. If we wanted the default to be, say, three options we would use:
[
[], [], []
]
If you don’t want to use the defaults from the original definition of option_value
and option_contents
, you can define them here:
[
[
'option_value' => 'new-value',
'option_contents' => 'Overriding the original defaults'
]
]
If you play around with the above, you’ll notice that the label for each set is the Option Contents for that set. This is enabled with templating. While the templating is not explained in the repeater documentation, it is demontrated there. So {{{ option_contents }}}
has a context of the current set. We could be more explicit by using Contents: {{{ option_contents }}}
, or we could add both the contents and the value by writing: {{{ option_contents }}} : {{{ option_value }}}
.
Rendering
The final step is to render the element. This is what the element will look like both on the front end and in the wp-admin’s Elementor preview.
Rendering a repeater entails usage of the get_settings_for_display
method. In Elementor speak, “settings” are the admin input to controls. In our case, we’re interested in the options_list
setting:
get_settings_for_display('options_list');
echo "
Wrapping up
… and with that we’re done with our basic custom Elementor widget. Of course if you wanted to add such a widget to your Elementor plugin library, you’d have to make a few modifications. You’d have to think about how to incorporate the dropdown into either a form or add JavaScript functionality to it. You’d probably want to add some styling. Since styling select elements is difficult you might want to do this via JavaScript with something like Select2 or Vue. The solutions to these are not very Elementor dependent. If you’re familiar with Wordpress and JavaScript, you should be able to figure it out!
The syntax highlights in this post were created using our own custom Elementor syntax highlighting widget.
References
- Elementor Developer Docs
- Elementor.com: Developer Reference
- Elementor.com: JavaScript Hooks
- Elementor.com: Registering new styles and scripts
- Elementor.com: Creating a New Control
- Elementor.com: Creating a New Widget
- BenMarshall.com: Build Custom Elementor Widgets – The Right Way
- Artbees.com: Creating a New Widget
- Plugin: Elementor Addons & Templates – Sizzify Lite
- Plugin: WidgetKit for Elementor
- Awesome Elemntor References