Dynamic Tags

Elementor 2.0 introduced a new type of data source called “Dynamic tag” which can pull its data dynamically form its source for example: Post Excerpt, Post Content, Author Info, Archive Title, Site Name, Site Logo and many more. If you use the WordPress native custom fields, ACF, Toolset or PODS you can use the fields values as dynamic data.

Creating a Custom Dynamic tag

Start by creating a class that extends the Elementor\Core\DynamicTags\Tag class and fill in all the required methods.
Each Dynamic Tag needs to have a few basic settings like a unique name, a title that will be used. On top of that, we have some advanced settings like the Dynamic Tag controls which are basically optional fields where the user can configure his custom data. And a render method that generates the final output based on the user settings from the Dynamic Tag’s controls.

Dynamic Tag Structure

As mentioned above, Elementor Dynamic Tag extends the Elementor\Core\DynamicTags\Tag class and inherits its methods. A simple Dynamic Tag skeleton will look like this:

Class Elementor_Test_Tag extends \Elementor\Core\DynamicTags\Tag {
	public function get_name() {}

	public function get_title() {}

	public function get_group() {}

	public function get_categories() {}

	protected function _register_controls() {}

	public function render() {}
}

Let’s break it down:

  • get_name() – Return a Tag name (id) that will be used in the code .
  • get_title() – Return the Tag title that will be displayed as the Tag label.
  • get_group() – Return which group the Tag will appear under. (tag groups will be explaind later on).
  • get_categories() – Return the controls categories the Tag belongs to. (tag categories will be explained later on).
  • _register_controls() – (Optional) Define Tag controls (setting fields) .
  • render() – The Tag output.

The Elementor\Core\DynamicTags\Tag class has many more methods you can use to do different things, but for now, this should be good enough.

Simple Dynamic Tag

To put all of the pieces together we are going to create a simple Elementor Dynamic Tag which will return a server variable.

Dynamic Tag Class

First we need to create a class that extends the Elementor\Core\DynamicTags\Tag class:

Class Elementor_Server_Var_Tag extends \Elementor\Core\DynamicTags\Tag {
}

Dynamic Tag settings

Now that we have a class for our dynamic tag, we can start filling in the methods, and we start with the simple ones:

Class Elementor_Server_Var_Tag extends \Elementor\Core\DynamicTags\Tag {
	public function get_name() {
		return 'server-variable';
	}

	public function get_title() {
		return __( 'Server Variable', 'elementor' );
	}

	public function get_group() {
		return 'request-variables';
	}

	public function get_categories() {
		return [ \Elementor\Modules\DynamicTags\Module::TEXT_CATEGORY ];
	}
}
Side Note: Dynamic tags categories
By default, Elementor comes with these dynamic tag categories:

  • TEXT_CATEGORY – Dynamic tags text controls.
  • URL_CATEGORY – Dynamic tags URL controls.
  • IMAGE_CATEGORY – Dynamic tags image controls.
  • MEDIA_CATEGORY – Dynamic tags media controls.
  • POST_META_CATEGORY – Dynamic tags post meta controls.
  • GALLERY_CATEGORY – Dynamic tags gallery controls.

Dynamic Tag Controls

Next, we need to add the Dynamic Tag controls using the _register_controls() method:

Class Elementor_Server_Var_Tag extends \Elementor\Core\DynamicTags\Tag {
	protected function _register_controls() {
		$variables = [];
		foreach ( array_keys( $_SERVER ) as $variable ) {
			$variables[ $variable ] = ucwords( str_replace( '_', ' ', $variable ) );
     		}

		$this->add_control(
			'param_name',
			[
				'label'   => __( 'Param Name', 'elementor' ),
			        'type' => \Elementor\Controls_Manager::SELECT,
			        'options' => $variables,
			]
		);
	}
}

We add a single select control with the list of the sever variables to choose from. Note that this is just an example, and in a real-world use case you would probably want to exclude some of the server variables.

Dynamic Tag Value

Last, we need to implement the render() method, which takes the variable name the user selected in the control and returns the server corresponding variable value:

Class Elementor_Server_Var_Tag extends \Elementor\Core\DynamicTags\Tag {
	public function render() {
		$param_name = $this->get_settings( 'param_name' );

		if ( ! $param_name ) {
			return;
		}

		if ( ! isset( $_SERVER[ $param_name ] ) ) {
			return;
		}

		$value = $_SERVER[ $param_name ];
		echo wp_kses_post( $value );
	}
}

The render() method simply checks that a server variable with the selected param name exists and echo it to the buffer after some minimal escaping.

The Entire Code

Altogether the Dynamic tag class with some extra phpDocs should look something like this:

<?php
Class Elementor_Server_Var_Tag extends \Elementor\Core\DynamicTags\Tag {

	/**
	* Get Name
	*
	* Returns the Name of the tag
	*
	* @since 2.0.0
	* @access public
	*
	* @return string
	*/
	public function get_name() {
		return 'server-variable';
	}

	/**
	* Get Title
	*
	* Returns the title of the Tag
	*
	* @since 2.0.0
	* @access public
	*
	* @return string
	*/
	public function get_title() {
		return __( 'Server Variable', 'elementor-pro' );
	}
   
	/**
	* Get Group
	*
	* Returns the Group of the tag
	*
	* @since 2.0.0
	* @access public
	*
	* @return string
	*/
	public function get_group() {
		return 'request-variables';
	}

	/**
	* Get Categories
	*
	* Returns an array of tag categories
	*
	* @since 2.0.0
	* @access public
	*
	* @return array
	*/
	public function get_categories() {
		return [ \Elementor\Modules\DynamicTags\Module::TEXT_CATEGORY ];
	}

	/**
	* Register Controls
	*
	* Registers the Dynamic tag controls
	*
	* @since 2.0.0
	* @access protected
	*
	* @return void
	*/
	protected function _register_controls() {

		$variables = [];

		foreach ( array_keys( $_SERVER ) as $variable ) {

			$variables[ $variable ] = ucwords( str_replace( '_', ' ', $variable ) );
		}

		$this->add_control(
			'param_name',
			[
				'label' => __( 'Param Name', 'elementor-pro' ),
				'type' => \Elementor\Controls_Manager::SELECT,
				'options' => $variables,
			]
		);
	}

	/**
	* Render
	*
	* Prints out the value of the Dynamic tag
	*
	* @since 2.0.0
	* @access public
	*
	* @return void
	*/
	public function render() {
		$param_name = $this->get_settings( 'param_name' );

        	if ( ! $param_name ) {
			return;
		}

		if ( ! isset( $_SERVER[ $param_name ] ) ) {
			return;
		}
	
		$value = $_SERVER[ $param_name ];
		echo wp_kses_post( $value );
	}
}

Register the Dynamic Tag

So after we have our dynamic tag class ready all that we have to do is register the tag with Elementor’s Dynamic tag manager at the elementor/dynamic_tags/register_tags hook:

<?php
add_action( 'elementor/dynamic_tags/register_tags', function( $dynamic_tags ) {
	// In our Dynamic Tag we use a group named request-variables so we need 
	// To register that group as well before the tag
	\Elementor\Plugin::$instance->dynamic_tags->register_group( 'request-variables', [
		'title' => 'Request Variables' 
	] );

	// Include the Dynamic tag class file
	include_once( 'path/to/dynamic/tag/class/file' );

	// Finally register the tag
	$dynamic_tags->register_tag( 'Elementor_Server_Var_Tag' );
} );

Final Notes:

  • You should only include the Dynamic Tag class on the elementor/dynamic_tags/register_tags hook to make sure Elementor’s autoloader loads all base classes for you.
  • For URL, Image, Media and Gallery controls, you need to extend Elementor\Core\DynamicTags\Data_Tag instead.
    There are many types of controls you can add to your widget to make it easier to configure. We have a separate section with a full list of available controls.