During my freelance missions in the development of sites with Elementor, I discovered several features of this page builder that are more or less documented (or not at all). I decided to gather these “tricks” in an article so that they can benefit the largest number of people.
So I’ll come to feed this list as I discover them, and feel free to participate in the comments 🙂 !
Summary
- Programmatically define Elementor colour palettes
- Adding custom fonts
- Injecting controls at a specific location
- Adding attributes to an existing widget
- Updating an existing control
- Create a custom widget category
Programmatically define Elementor colour palettes
Elementor offers to manage color palettes in two places:
The general color palette:
The widget’s color pickers:
These color palettes are stored in the database as options, so it is possible to define and update them programmatically.
To define the general colors it is necessary to update the elementor_scheme_color
option, and for the color selector it is the elementor_scheme_color-picker
option.
Here are two functions that are used to declare color arrays, note the keys :
// define a main colors scheme
function prefix_color_scheme( $colors = array() ) {
$colors = [
'1' => '#ddd',
'2' => '#000',
'3' => '#454545',
'4' => '#D34D4D',
];
return $colors;
}
// define a colors scheme for color picker
function prefix_color_scheme_picker( $colors_picker = array() ) {
$colors_picker = [
'1' => '#fff',
'2' => '#000',
'3' => '#ccc',
'4' => '#F20000',
'5' => '#1EBA0E',
'6' => '#182FC2',
];
return $colors_picker;
}
Code language: PHP (php)
Here is the function that allows you to update the database options when switching of theme (to be adapted on another action if necessary):
// update elementor color scheme on switch theme
add_action( 'after_switch_theme', 'prefix_update_elementor_scheme_color' );
function prefix_update_elementor_scheme_color() {
$colors = prefix_color_scheme();
if ( $colors ) {
update_option( 'elementor_scheme_color', $colors );
}
$colors_picker = prefix_color_scheme_picker();
if ( $colors_picker ) {
update_option( 'elementor_scheme_color-picker', $colors_picker );
}
}
Code language: PHP (php)
Adding custom fonts
Elementor offers a tool to add custom fonts from the dashboard by uploading fonts files.
However, if you want to add new fonts without using this tool, for example to get your hands on CSS, or because your files already exist, there are two filters availables :
elementor/fonts/groups
which allows you to add a new group of fonts, for example “Theme fonts”:
/**
* Add Font Group to Elementor
*/
add_filter( 'elementor/fonts/groups', 'prefix_elementor_custom_fonts_group', 10, 1 );
function prefix_elementor_custom_fonts_group( $font_groups ) {
$font_groups['theme_fonts'] = __( 'Theme Fonts' );
return $font_groups;
}
Code language: PHP (php)
elementor/fonts/additional_fonts
which allows us to add new fonts to our previously created group :
/**
* Add Group Fonts to Elementor
*/
add_filter( 'elementor/fonts/additional_fonts', 'prefix_elementor_custom_fonts', 10, 1 );
function prefix_elementor_custom_fonts( $additional_fonts ) {
// Key/value
//Font name/font group
$additional_fonts['Custom font'] = 'theme_fonts';
return $additional_fonts;
}
Code language: PHP (php)
Your new font will now appear in all Elementor font selectors 🙂
If this is not done, you still have to load your font files in your theme or extension and add the CSS rules of @font-face
to your style sheet.
Injecting controls at a specific location
Elementor has a method that allows you to inject elements at a specific location in a widget, for example before or after an existing control.
The methods to be used are start_injection
to start the injection, and end_injection
to end it (start_injection documentation).
The function below allows you to add a new text control to the Button widget, before ('at' => 'before'
) the existing “Link” control ('of' => 'link'
).
/**
* Add injection
*
* Used to inject controls and sections to a specific position in the stack.
*
* @param Element_Base $element The edited element.
* @param array $args Section arguments.
*
*/
function add_injection( $element, $args ) {
// start injection of control before an other control
$element->start_injection( [
'at' => 'before',
'of' => 'link',
] );
// add control
$element->add_control(
'button_custom_control',
[
'label' => __( 'Custom control', 'textdomain' ),
'type' => \Elementor\Controls_Manager::TEXT,
'default' => 'default value',
]
);
// end injection just after
$element->end_injection();
}
Code language: PHP (php)
Next, you must add the function at the end of the section where the control you are positioning on is located.
Here, the main section is the section_button
identifier, so we can use the hook elementor/element/{$section_name}/{$section_id}/before_section_end
(documentation) like this :
add_action( 'elementor/element/button/section_button/before_section_end', 'add_injection', 10, 2 );
Code language: JavaScript (javascript)
Adding attributes to an existing widget
After injecting a control to an existing widget, you may want to add an attribute (HTML) to the widget depending on the value of that control.
Pour ajouter des attributs HTML dans le rendu d’un widget Elementor, on utilise la méthode add_render_attribute
(documentation). On lui passe en paramètres :
To add HTML attributes in the render of an Elementor widget, use the method add_render_attribute
(documentation). We pass to it in parameters :
- HTML element (used later to display attributes)
- Key of the attribute (class, ID, or whatever you want)
- Attribute value
- overwrite (true/false if we want to overwrite existing attributes)
To add an attribute to an existing widget, you have to act before the widget content is displayed, there is the hook elementor/widget/before_render_content
.
Based on the previous example where we add a text type control, we can imagine using the value of this control to populate a “data-custom-control” attribute, we will do it with the following code:
/**
* Before widget render content.
*
* Add custom attributes to button widget link
*
* @since 1.0.0
*
* @param Widget_Base $this The current widget.
*/
add_action( 'elementor/widget/before_render_content', 'prefix_add_button_custom_attribute', 10, 1 );
function prefix_add_button_custom_attribute( $widget ) {
if ( 'button' === $widget->get_name() ) { // if button is current widget
$settings = $widget->get_settings(); // get widget setting
// if setting exist and not empty
if ( isset( $settings[ 'button_custom_control' ] ) && ! empty( $settings[ 'button_custom_control' ] ) ) {
// add custom attribute to button
$widget->add_render_attribute( 'button', 'data-custom-control', $settings[ 'button_custom_control' ] );
}
}
}
Code language: PHP (php)
With this function, the content of the control that has the button_custom_control
identifier will be displayed on the button link in the data-custom-control attribute.
Note that the $widget
variable is used to access the current widget object and all its properties and methods, including get_settings()
which allows you to retrieve its settings.
If you wonder how the attributes are then displayed, take a look at the Button widget class (elementor/includes/widgets/button.php), function render
:
<div <?php echo $this->get_render_attribute_string( 'wrapper' ); ?>>
<a <?php echo $this->get_render_attribute_string( 'button' ); ?>>
<?php $this->render_text(); ?>
</a>
</div>
Code language: PHP (php)
The get_render_attribute_string
method is used, and this is where we find the HTML button element that is passed as the first parameter of add_render_attribute
.
Feel free to use these methods in your own widgets, they allow us to build our logic upstream, add several attributes according to different conditions, and display everything cleanly at once.
Updating an existing control
Elementor has the update_control
method which allows you to update an existing control. It is very similar to add_control
: you use the identifier of the targeted control and define in an array the parameters you want to update. You can modify and/or add any of the options available for the control. (update_control documentation)
For example, to set a default alignment value to the Button widget and also hide the alignment control if the button type is different from the “info” value:
function prefix_update_controls( $element, $args ) {
// update "align" control, set default value to "center"
// add condition : show control only if button type is not "info"
$element->update_control(
'align',
[
'default' => 'center',
'condition' => [
'button_type!' => 'info',
],
]
);
}
Code language: PHP (php)
Un auAnother example, to add a new style option (“Fiesta”) for the “Border” control, and set the border color to #000 by default :
function prefix_update_controls( $element, $args ) {
// update "border" control, add custom style option "Fiesta"
// update "border" control, set default value to "solid"
$element->update_control(
'border_border',
[
'options' => [
'' => __( 'None', 'elementor' ),
'dashed groove double dotted' => _x( 'Fiesta', 'Border Control', 'elementor' ),
'solid' => _x( 'Solid', 'Border Control', 'elementor' ),
'double' => _x( 'Double', 'Border Control', 'elementor' ),
'dotted' => _x( 'Dotted', 'Border Control', 'elementor' ),
'dashed' => _x( 'Dashed', 'Border Control', 'elementor' ),
'groove' => _x( 'Groove', 'Border Control', 'elementor' ),
],
'default' => 'solid',
]
);
// update "border color" control, set default value to "#000"
$element->update_control(
'border_color',
[
'default' => '#000',
]
);
}
Code language: PHP (php)
Next, you must add the function at the end of the section where the control you are positioning on is located.
Here, it is the style section which has the section_style
identifier, so we can use the hook elementor/element/{$section_name}/{$section_id}/after_section_end
(documentation) like this :
add_action( 'elementor/element/button/section_style/after_section_end', 'prefix_update_controls', 10, 2 );
Code language: JavaScript (javascript)
Create a custom widget category
In Elementor, widgets are categorized in the sidebar. Natively we find for example the following categories :
- Basic
- Pro
- General
But did you know that it is possible to create your own categories to better organize your own widgets? Elementor makes it possible with the hook elementor/elements/categories_registered
(documentation), here is an example of a function that adds a “Theme” category:
function prefix_add_elementor_widget_categories( $elements_manager ) {
$elements_manager->add_category(
'my-theme', // category ID (unique)
[
'title' => __( 'My Theme', 'textdomain' ), // Category public name
'icon' => 'eicon-plus', // category icon
]
);
}
add_action( 'elementor/elements/categories_registered', 'prefix_add_elementor_widget_categories' );
Code language: PHP (php)
With this feature, you’ll see your new category appear in the widget sidebar, you can even add an icon (chosen from Elementor’s icon library).
Then, when you create your widgets, just use the native get_categories
method (inherited from the Widget_Base
class) and specify your category identifier (note that you can assign several categories to the same widget) :
public function get_categories() {
return [ 'my-theme, 'basic' ];
}
Code language: PHP (php)
4 responses to “Elementor Development Tips and Tricks”
Hi Marie, thank you for writing this article. I am usually searching for hours trying to find out how I can extend Elementor. And it then turns out to just be 1 or 2 rows of code which I needed to add. Maybe this is all written in their documentation but for some reason I am not able to find it in their – so I am very glad that people like you provide these helpful information :-).
I have one question about the part where we add an attribute to an existing widget. You describe how to use the hook elementor/widget/before_render_content and this is all clear and working well but I cannot find any information on how to hook into the addRenderAttribute on the javascript level in the content_template function to render the preview correctly as well.
Can you add this here please if you happen to know? This would be awesome 🙂
Cheers Britta
Good article with useful details. I found some key features that I have been looking for. Maybe you know: Is it possible to nest two repeaters inside each other (in the controller) as a sub repeater?
Gald it helps you.
As I know, no it’s not possible to nest repeater inside a repeater.
thanks Marie .
I need add custom controler in after section for custom header settings. but not working elementor/element/section/section_layout/after_section_end in New Elementor with Container mode .
Can I help me ?
my code is :
add_action( ‘elementor/element/section/section_structure/after_section_end’, function ( $section, $args ) { $section->start_controls_section( ‘header_custom_class’, [ ‘label’ => __( ‘For Header’, ‘theme’ ), ‘tab’ => \Elementor\Controls_Manager::TAB_LAYOUT, ] ); $section->add_control( ‘sticky_class’, [ ‘label’ => __( ‘Sticky On/Off’, ‘theme’ ), ‘type’ => Elementor\Controls_Manager::SWITCHER, ‘return_value’ => ‘is-fixed’, ‘prefix_class’ => ”, ] ); $section->end_controls_section();}, 10, 2 )
ads this link write issue :
https://github.com/elementor/elementor/issues/24043
thanks .