Elementor Development Tips and Tricks

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

Elementor offers to manage color palettes in two places:

The general color palette:

screenshot of the general color palette

The widget’s color pickers:

capture d'écran du sélecteur de couleurs des widgets

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

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

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

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

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();
}

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 );

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' ] );
		}
	}
}

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>

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',
			],
		]
	);
}

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',
		]
	);
}

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 );

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' );

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' ];
}

Posted by: Marie Comet

Freelance web developer and integrator, specialized in WordPress.

Follow me on:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

dapibus Curabitur eleifend id vulputate, id, risus risus.