Build Custom Elementor Widgets — The Right Way!

Add/Change Elementor Content Tab You can add/change the content tab and options that appear within them in the Elementor editor sidebar with the following: widgets/awesomesauce.php – In the _register_controls method. Add/Change Elementor Style Tab You can add/change the style tab and options that appear within them in the Elementor editor sidebar with the following: widgets/awesomesauce.php … Read article

Add/Change Elementor Content Tab

You can add/change the content tab and options that appear within them in the Elementor editor sidebar with the following:

widgets/awesomesauce.php – In the _register_controls method.

$this->start_controls_section(
  'section_content',
  [
    'label' => __( 'Content', 'elementor-awesomesauce' ),
  ]
);

/* Add the options you'd like to show in this tab here */

$this->end_controls_section();

Add/Change Elementor Style Tab

You can add/change the style tab and options that appear within them in the Elementor editor sidebar with the following:

widgets/awesomesauce.php – In the _register_controls method.

$this->start_controls_section(
  'style_section',
  [
    'label' => __( 'Style Section', 'elementor-awesomesauce' ),
    'tab' => \Elementor\Controls_Manager::TAB_STYLE,
  ]
);

/* Add the options you'd like to show in this tab here */

$this->end_controls_section();

Elementor Widget Image Field

The ability to add/change images is crucial to any good WordPress theme, here’s how to add a custom image field in an Elementor widget with Controls_Manager::MEDIA:

widgets/awesomesauce.php – In the _register_controls method.

$this->add_control(
			'mask_image',
			[
				'label' => __( 'Mask Image', 'elementor-awesomesauce' ),
				'type' => Controls_Manager::MEDIA,
        'default' => [
					'url' => Utils::get_placeholder_image_src(),
				]
			]
		);

What if we wanted to allow the user to select the HTML element for the title, it’s also a cinch with Controls_Manager::SELECT:

widgets/awesomesauce.php – At the top of the file where the use statements are located.

use Elementor\Utils;

widgets/awesomesauce.php – In the _register_controls method.

$this->add_control(
  'mask_image',
  [
    'label' => __( 'Mask Image', 'elementor-awesomesauce' ),
    'type' => Controls_Manager::MEDIA,
    'default' => [
      'url' => Utils::get_placeholder_image_src(),
    ]
  ]
);

Elementor Widget Button Group

How about adding alignment options using a button group, easy with Controls_Manager::CHOOSE:

widgets/awesomesauce.php – In the _register_controls method.

$this->add_control(
  'text_align',
  [
    'label' => __( 'Alignment', 'elementor-awesomesauce' ),
    'type' => \Elementor\Controls_Manager::CHOOSE,
    'options' => [
      'left' => [
        'title' => __( 'Left', 'elementor-awesomesauce' ),
        'icon' => 'fa fa-align-left',
      ],
      'center' => [
        'title' => __( 'Center', 'elementor-awesomesauce' ),
        'icon' => 'fa fa-align-center',
      ],
      'right' => [
        'title' => __( 'Right', 'elementor-awesomesauce' ),
        'icon' => 'fa fa-align-right',
      ],
    ],
    'default' => 'center',
    'toggle' => true,
  ]
);

Elementor Widget Typography Options

Elementor comes with a powerful typography editor that includes responsive options, here’s how you add it with Group_Control_Typography & Scheme_Typography::TYPOGRAPHY_1.

widgets/awesomesauce.php – At the top of the file where the use statements are located.

use Elementor\Group_Control_Typography;
use Elementor\Scheme_Typography;

widgets/awesomesauce.php – In the _register_controls method.

$this->add_group_control(
  Group_Control_Typography::get_type(),
  [
    'name'     => 'content_typography',
    'label'    => __( 'Typography', 'elementor-awesomesauce' ),
    'scheme'   => Scheme_Typography::TYPOGRAPHY_1,
    'selector' => '{{WRAPPER}} .elementor-awesomesauce',
    'fields_options' => [
      'letter_spacing' => [
        'range' => [
          'min' => 0,
          'max' => 100
        ]
      ]
    ]
  ]
);
1 2

Comments

  1. Mark L Wood-Patrick February 25, 2020

    Many thanks for the presentation, very helpful. I have a question about php code style. When I look at the page: https://developers.elementor.com/getting-started/ it understandably recommends using phpcs using the wordpress coding standard but when I run phpcs on the elementor source a few problems are consistently reported:

    Class file names should be based on the class name with “class-” prepended. Expected class-control-button.php, but found button.php.

    Missing file doc comment

    Short array syntax is not allowed

    I’m using the current WordPress rules as far as I can see. Do you know where I can I find a phpcs rule set which matches what the elementor team are doing in practice? When I look at a well used plugin that works with Elementor such as Ocean Extra I see a lot more violations. Any pointers would be much appreciated.

    • That’s pretty common with WP plugins & themes. Unfortunately, it’s the wild west when it comes to code quality in WP plugins.

    • Mark L Wood-Patrick February 28, 2020

      Is there a github repository with the code from this article. I’m seeing some phpcs issues in my build of this code and would appreciate your comments on the reported issues , which issues I should ignore and which should be fixed and best way to fix them

      FOUND 10 ERRORS AND 2 WARNINGS AFFECTING 8 LINES
      ———————————————————————————————————————– 1 | ERROR | Class file names should be based on the class name with “class-” prepended. Expected
      | | class-awesomesauce.php, but found awesomesauce.php.
      1 | ERROR | Missing file doc comment
      12 | ERROR | Inline comments must end in full-stops, exclamation marks, or question marks
      15 | ERROR | Missing short description in doc comment
      87 | WARNING | Method name “_register_controls” should not be prefixed with an underscore to indicate visibility 217 | ERROR | All output should be run through an escaping function (see the Security sections in the WordPress | | Developer Handbooks), found ‘$this’.
      217 | ERROR | All output should be run through an escaping function (see the Security sections in the WordPress | | Developer Handbooks), found ‘$settings[‘title’]’.
      218 | ERROR | All output should be run through an escaping function (see the Security sections in the WordPress | | Developer Handbooks), found ‘$this’.
      218 | ERROR | All output should be run through an escaping function (see the Security sections in the WordPress | | Developer Handbooks), found ‘$settings[‘description’]’.
      219 | ERROR | All output should be run through an escaping function (see the Security sections in the WordPress | | Developer Handbooks), found ‘$this’.
      219 | ERROR | All output should be run through an escaping function (see the Security sections in the WordPress | | Developer Handbooks), found ‘$settings[‘content’]’.
      232 | WARNING | Method name “_content_template” should not be prefixed with an underscore to indicate visibility

  2. Built my first widget! Thanks for the help.

    I have a question. I found the Elementor documentation on adding a new category, but can’t figure out in which file and where to place the code. Does anyone know?

    • Put it in the Plugin class:

      public function register_categories( $elements_manager ) {
          $elements_manager->add_category(
            'categorykey',
            [
              'title' => __( 'Category Name', 'textdomain' ),
              'icon' => 'fa fa-plug',
            ]
          );
        }
  3. Awsome stuff.
    I was about to start on a basic plugin, then looked at the oceanwp elementor addons plugin which looked really complicated.
    Then I found this which is obviously what they used as well and now have a well-structured custom widgets plugin.

    Thank you!

  4. hi thanks for everything it was so much helpful .. can you please help me i want to know how can i register style just like script

    • Hello,
      Good tutorial,
      How can i add more widgets? Is there a way to make one file php for widget? Like elementor default have.

      Or what i want to do is to add some extra options to actual elementor widgets, ex background color and hover etc.

      Cheers

    • Craig Tommola February 13, 2020

      Same here – I followed this to the T and searched the docs too … adding to the plugins.php file didn’t work as expected …

      public function widget_styles() {
      wp_register_style( ‘elementor-awesomesauce’, plugins_url( ‘/assets/css/awesomesauce.css’, __FILE__ ) );
      }

      add_action( ‘elementor/frontend/after_enqueue_styles’, [ $this, ‘widget_styles’ ] );

    • In plugin.php, add this to the Plugin class:

      /**
         * widget_scripts
         *
         * Load required plugin core files.
         *
         * @access public
         */
        public function widget_scripts() {
          $plugin = get_plugin_data( __FILE__, false, false );
      
          wp_register_style( 'your-style', plugin_dir_url( __FILE__  ) . 'assets/css/file.css', [], $plugin['Version'] );
          wp_register_script( 'your-script', plugin_dir_url( __FILE__ ) . 'assets/js/file.js', [ 'jquery' ], $plugin['Version'], true );
        }
      

      Then in your widget class add the following to call the scripts when the widget is loaded:

      public function get_style_depends() {
          $styles = [ 'your-style' ];
      
          return $styles;
        }
      
        public function get_script_depends() {
          $scripts = [ 'your-script' ];
      
          return $scripts;
        }
      
  5. Sanjaya Dulal September 30, 2019

    Not working. I tired all above code .

    Well how can i implement it. Any idea ?

    i am bit confusion it.

  6. Himanshu July 17, 2019

    Wow , it worked perfectly ! Can you come up with any idea to register Custom Widget for “Single page” editor only ? I want to register a widget which will appear only in “Single” Editor .. Is it possible ?

    • If you’re trying to conditionally show/hide a widget in the frontend, try hooking into ‘elementor/widget/render_content’ .
      See https://code.elementor.com/php-hooks/#elementorwidgetrender_content

      If you’re trying to restrict certain widgets in the editor, I don’t think (maybe) there’s an action for that. Elementor provides a ‘Role Manager’ though. In the Pro version, there’s an option to ‘only allow them to edit existing content inside the editor’. This means you can publish/create a template beforehand, then whoever edits that page/template, can only edit the existing content in the editor (only the widgets you used for that template).

  7. Abe Caymo May 15, 2019

    Hey thanks for this great article btw!

    Could you add an example on responsive controls?
    More specifically, in the ‘Responsive Choose’ found in the https://developers.elementor.com/add-responsive-controls-to-widgets/ , what is the “prefix_class” used for?

    • That’s used to create a prefix for the alignment class. In their example, depending on the choice, the final class could be: content-align-left, content-align-right or content-align-center

  8. Abe Caymo May 10, 2019

    Just wow. I’m relatively new to coding and after going through this tutorial, now I understand what ‘good code documents itself’ means. Now I ACTUALLY understand more about OOP seeing it in action. Thanks a lot!

  9. This is really great! One thing I’m trying to do is create a custom Elementor widget that just runs some PHP where it is placed. Do you know if this is possible? I’ve been tinkering around but can’t quite get it to work. I actually don’t need any controls for the widget– it’s so I can place a custom action hook within my Elementor pages.

    • I’m sure there’s a plugin that enables PHP in the WP text widget. It might be possible to do it that way?

    • May not be understanding, but likely you don’t need the elementor widget. You just need to add your code into a core WP hook like init or wp. Which hook you choose will depend on your needs. You could also potentially create a simple shortcode that you can add into Elementor pages using the shortcode widget which can run anything you’d like with no output.

  10. Michael Bourne April 26, 2019

    This is better than the official docs. Kudos.

  11. Giovani Camara March 19, 2019

    This was ridiculously useful… I managed to get this all working which is great! Do you know if this awesomesauce plugin can only have one extension, or is it possible to have multiple widgets in this individual plugin? I renamed it all appropriate to my project, but I am having difficulties adding more widgets to it…. any ideas?

    • Glad you found it useful any Yup, you can add as many as you like! Look in plugin.php in the register_widgets method. Just follow the example for a new widget, then register it. Ex:

      private function include_widgets_files() {
        // First widget
        require_once( __DIR__ . '/widgets/awesomesauce.php' );
        // Second widget
        require_once( __DIR__ . '/widgets/awesomesauce2.php' );
      }
      
      public function register_widgets() {
        // Its is now safe to include Widgets files
        $this->include_widgets_files();
       
        // Register Widgets
        // First widget
        \Elementor\Plugin::instance()->widgets_manager->register_widget_type( new Widgets\Awesomesauce() );
        // Second widget
        \Elementor\Plugin::instance()->widgets_manager->register_widget_type( new Widgets\Awesomesauce2() );
      }

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.

All comments are held for moderation and only published when on topic and not rude. You'll even get little stars if you do an extra good job.

You may write comments in Markdown. This is the best way to post any code, inline like `<div>this</div>` or multiline blocks within triple backtick fences (```) with double new lines before and after.

Want to tell me something privately, like pointing out a typo or stuff like that? Contact Me.

icon-search icon-link