{"id":1097,"date":"2019-12-17T04:43:47","date_gmt":"2019-12-16T21:43:47","guid":{"rendered":"https:\/\/lab.wptips.dev\/?p=1097"},"modified":"2020-05-04T22:35:03","modified_gmt":"2020-05-04T15:35:03","slug":"elementor-widgets-to-match-designs","status":"publish","type":"post","link":"https:\/\/pixelstudio.id\/blog\/elementor-widgets-to-match-designs\/","title":{"rendered":"How to Modify Existing Elementor Widgets to Match Your Designs"},"content":{"rendered":"\n<p>There are many page builders already out, but I personally think that Elementor is better in every way. As a developer, I cannot describe the convenience this plugin provides.<\/p>\n\n\n\n<p>Before Elementor, if my clients would have a requirement for the custom design, I had to create a custom theme for them which is heavy on cost and time. Typically, clients are short on budget and I would be in a difficult situation.<\/p>\n\n\n\n<p>Elementor Pro has a Theme Builder which makes it very easy for us to create a custom design theme as per the client\u2019s requirement and in a very cost-effective way. Now I use Elementor for most of the projects.<\/p>\n\n\n\n<p>But&#8230; But&#8230;<\/p>\n\n\n\n<p>Nothing is perfect in this world. <strong>There will always be a case in which the widget or the addons you are using does not match your required design.<\/strong><\/p>\n\n\n\n<p>In this tutorial, we are going to learn the process of how to solve such problems. Let\u2019s start! <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Use-case:<\/h2>\n\n\n\n<p>The scenario is that we have a website with the Elementor plugin installed. We want to create a section on the homepage which will have 3 columns each including a thumbnail image, a title, a subtitle, and some description. <\/p>\n\n\n\n<p>Now, we will find the Elementor widget which is a close match to our design. Fortunately, we found one &#8211; <strong>the default Image Box<\/strong>. Image Box will allow us to have a thumbnail image, a title, and a description. <\/p>\n\n\n\n<p>Below is what we can achieve using the default Image Box:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1146\" height=\"386\" src=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/complete-section-default-tiny.jpg\" alt=\"\" class=\"wp-image-1122\" srcset=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/complete-section-default-tiny.jpg 1146w, https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/complete-section-default-tiny-480x162.jpg 480w\" sizes=\"auto, (max-width: 1146px) 100vw, 1146px\" \/><figcaption>Complete Section Using Default Image Box Widget<\/figcaption><\/figure>\n\n\n\n<p>But we need a subtitle field. This is what we want to finally achieve:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"540\" src=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/Default-and-Expectation.jpg\" alt=\"\" class=\"wp-image-1121\" srcset=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/Default-and-Expectation.jpg 960w, https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/Default-and-Expectation-480x270.jpg 480w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><figcaption>Default Vs Required<\/figcaption><\/figure>\n\n\n\n<p>The option to add the subtitle is not available in the default Image Box widget. If the description field would have been a WYSIWYG editor you could have added the subtitle in it and created a similar design. But it\u2019s a normal text box. <\/p>\n\n\n\n<p>You can, of course, create the same design by using separate widgets and then stack them together but if you are like me who needs strong solutions, below is the process for you. <\/p>\n\n\n\n<p>Let\u2019s build this step by step.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Create an Extension containing the Copy of Image Box Widget<\/h3>\n\n\n\n<p>We don&#8217;t want to modify the plugin&#8217;s code directly, so we will need to create a plugin that extends the Elementor Plugin.<\/p>\n\n\n\n<p>Since creating an extension from scratch would make a very long tutorial, we have prepared a starter plugin that already contains the Image Box widget:<\/p>\n\n\n\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link has-text-color has-light-orange-color has-background has-orange-background-color\" href=\"https:\/\/github.com\/DWebSoft\/elementor-extension-wptips-tutorial\" target=\"_blank\" rel=\"noreferrer noopener\">Get the Starter Plugin<\/a><\/div>\n\n\n\n<p>If you are interested to learn more, read <a href=\"https:\/\/developers.elementor.com\/creating-an-extension-for-elementor\/\">Elementor&#8217;s official doc<\/a> about the step by step process of creating an extension.<\/p>\n\n\n\n<p>For your reference, these are the necessary steps to copy a default widget into your extension:<\/p>\n\n\n\n<ol><li>Get the code in Elementor plugin folder > <code>includes<\/code> > <code>widgets<\/code> > <code>image-box.php<\/code>. <\/li><li>Change the class name, return value of  <code>get_name()<\/code> and  <code>get_title()<\/code>. Otherwise, there will be a conflict with an old and new widget.<\/li><li>Make sure to use the appropriate namespaces otherwise some classes will not load and you will see a spinner loading in your Elementor Panel. And that won&#8217;t give any error which is very hard to debug.<\/li><li>Then you will need to require this file and register our new widget into <code>init_widgets()<\/code> of your main extension file.<\/li><\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Check Whether the New Widget is Installed Properly<\/h3>\n\n\n\n<p>First, activate the extension plugin. Then create a new page and try adding the new widget which is called &#8220;WP Tips Image Box&#8221;.<\/p>\n\n\n\n<p>If you can find the new widget, it is time to get dirty with code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Add a new field for Subtitle<\/h3>\n\n\n\n<p>We are going to add a new field in &#8220;Content&#8221; tab as shown in the picture below:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"540\" src=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/Content-Tab-Options.jpg\" alt=\"\" class=\"wp-image-1120\" srcset=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/Content-Tab-Options.jpg 960w, https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/Content-Tab-Options-480x270.jpg 480w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><figcaption>Content Tab Options<\/figcaption><\/figure>\n\n\n\n<p>Open <code>image-box.php<\/code> and look for the code below (around line no. 131):<\/p>\n\n\n\n<pre title=\"widgets\/image-box.php\" class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">$this->add_control(\n  'title_text',\n  [\n    'label' => __( 'Title, Subtitle &amp; Description', 'elementor' ),\n    ...\n  ]\n);<\/code><\/pre>\n\n\n\n<p>After that code, add a control for our new subtitle field: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">$this->add_control(\n  'subtitle_text',\n  [\n    'label' => __('Subtitle', 'elementor'),\n    'type' => Controls_Manager::TEXT,\n    'dynamic' => [\n      'active' => true,\n    ],\n    'default' => __('This is the subtitle', 'elementor'),\n    'placeholder' => __('Enter your subtitle', 'elementor'),\n    'show_label' => false,\n    'label_block' => true,\n  ]\n);<\/code><\/pre>\n\n\n\n<p>Save the file and you should see a new subtitle field in your widget.<\/p>\n\n\n\n<p>Now, at the end of the Content tab, you can see that we have an option to set an HTML tag for the title. We need to have the same option for our subtitle too.<\/p>\n\n\n\n<p>Look for the code (around line no. 215): <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">$this->add_control(\n  'title_size',\n  [\n    'label' => __( 'Title HTML Tag', 'elementor' ),\n    'type' => Controls_Manager::SELECT,\n    ...\n  ]\n);<\/code><\/pre>\n\n\n\n<p> After that code, add a similar option for selecting an HTML tag for the subtitle:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">$this->add_control(\n  'subtitle_size',\n  [\n    'label' => __( 'Subtitle HTML Tag', 'elementor' ),\n    'type' => Controls_Manager::SELECT,\n    'options' => [\n      'h1' => 'H1',\n      'h2' => 'H2',\n      'h3' => 'H3',\n      'h4' => 'H4',\n      'h5' => 'H5',\n      'h6' => 'H6',\n      'div' => 'div',\n      'span' => 'span',\n      'p' => 'p',\n      ],\n    'default' => 'h5',\n  ]\n);<\/code><\/pre>\n\n\n\n<p>Refresh the page and you will see this option at the bottom of the &#8216;Content&#8217; tab.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Create options to style the subtitle. <\/h3>\n\n\n\n<p>If you goto &#8216;Style&#8217; tab for the new Image Box widget, you will see that we have multiple options to style the title. We need to add similar ones for the subtitle.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"540\" src=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/Style-Tab-Options.jpg\" alt=\"\" class=\"wp-image-1119\" srcset=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/Style-Tab-Options.jpg 960w, https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/Style-Tab-Options-480x270.jpg 480w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><figcaption>Style Tab Options<\/figcaption><\/figure>\n\n\n\n<p>Let\u2019s create new style controls for the subtitle. Look for the code below ( around line no. 522):<\/p>\n\n\n\n<pre title=\"widgets\/image-box.php\" class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">$this->add_group_control(\n  Group_Control_Typography::get_type(),\n  [\n    'name' => 'title_typography',\n    ...\n  ]\n);<\/code><\/pre>\n\n\n\n<p>After that code, add similar styling options for the subtitle. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">$this->add_control(\n  'heading_subtitle',\n  [\n    'label' => __('Subtitle', 'elementor'),\n    'type' => Controls_Manager::HEADING,\n    'separator' => 'before',\n  ]\n);\n\n$this->add_responsive_control(\n  'subtitle_bottom_space',\n  [\n    'label' => __('Spacing', 'elementor'),\n    'type' => Controls_Manager::SLIDER,\n    'range' => [\n      'px' => [\n        'min' => 0,\n        'max' => 100,\n      ],\n    ],\n    'selectors' => [\n      '{{WRAPPER}} .elementor-image-box-subtitle' => 'margin-bottom: {{SIZE}}{{UNIT}};',\n    ],\n  ]\n);\n\n$this->add_control(\n  'subtitle_color',\n  [\n    'label' => __('Color', 'elementor'),\n    'type' => Controls_Manager::COLOR,\n    'default' => '',\n    'selectors' => [\n      '{{WRAPPER}} .elementor-image-box-content .elementor-image-box-subtitle' => 'color: {{VALUE}};',\n    ],\n    'scheme' => [\n      'type' => Schemes\\Color::get_type(),\n      'value' => Schemes\\Color::COLOR_1,\n    ],\n  ]\n);\n\n$this->add_group_control(\n  Group_Control_Typography::get_type(),\n  [\n    'name' => 'subtitle_typography',\n    'selector' => '{{WRAPPER}} .elementor-image-box-content .elementor-image-box-subtitle',\n    'scheme' => Schemes\\Typography::TYPOGRAPHY_1,\n  ]\n);<\/code><\/pre>\n\n\n\n<p>Refresh the page and you will see new styling options in the &#8216;Style&#8217; tab under Content Section. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Add the HTML markup to display the subtitle on the page. <\/h3>\n\n\n\n<p>To modify the HTML that is being displayed as an output of the Widget, we need to make changes in the <code>render()<\/code> function. <\/p>\n\n\n\n<p>Find the code below in the render function (around line no: 668)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">if ( ! Utils::is_empty( $settings['title_text'] ) ) {\n  $this->add_render_attribute( 'title_text', 'class', 'elementor-image-box-title' );\n  ...\n}<\/code><\/pre>\n\n\n\n<p>This code displays the title on the web page. <\/p>\n\n\n\n<p>After that code, add the code below to render the subtitle:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">if (!Utils::is_empty($settings['subtitle_text'])) {\n  $this->add_render_attribute('subtitle_text', 'class', 'elementor-image-box-subtitle');\n\n  $this->add_inline_editing_attributes('subtitle_text', 'none');\n\n  $subtitle_html = $settings['subtitle_text'];\n\n  $html .= sprintf('&lt;%1$s %2$s>%3$s&lt;\/%1$s>', $settings['subtitle_size'], $this->get_render_attribute_string('subtitle_text'), $subtitle_html);\n}<\/code><\/pre>\n\n\n\n<p>Refresh the page and you will see the subtitle is being displayed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6: Add Javascript code. <\/h3>\n\n\n\n<p>This is our last step. You can see that if you make any changes to the text or styles of the subtitle, they are not reflected immediately. <\/p>\n\n\n\n<p>This is because we have not added any Javascript to reflect changes immediately. <\/p>\n\n\n\n<p>Find the code below in <code>_content_template()<\/code> function (around line no. 746).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">if ( settings.title_text ) {\n  var title_html = settings.title_text;\n  ...\n}<\/code><\/pre>\n\n\n\n<p>After that code, add the code below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">if ( settings.subtitle_text ) {\n  var subtitle_html = settings.subtitle_text;\n\n  view.addRenderAttribute( 'subtitle_text', 'class', 'elementor-image-box-subtitle' );\n\n  view.addInlineEditingAttributes( 'subtitle_text', 'none' );\n\n  html += '&lt;' + settings.subtitle_size  + ' ' + view.getRenderAttributeString( 'subtitle_text' ) + '>' + subtitle_html + '&lt;\/' + settings.subtitle_size  + '>';\n}<\/code><\/pre>\n\n\n\n<p>Now if you go back and refresh the page, you will see the changes reflected immediately if you try to edit content or styles of the subtitle.<\/p>\n\n\n\n<p>This is how your final output should look:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1143\" height=\"403\" src=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/final-output.jpg\" alt=\"\" class=\"wp-image-1118\" srcset=\"https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/final-output.jpg 1143w, https:\/\/pixelstudio.id\/blog\/wp-content\/uploads\/2019\/12\/final-output-480x169.jpg 480w\" sizes=\"auto, (max-width: 1143px) 100vw, 1143px\" \/><figcaption>Final Output<\/figcaption><\/figure>\n\n\n\n<hr class=\"wp-block-separator is-style-dots\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>I know this was a long tutorial to follow. But once you understand the process for how you should modify the Elementor widget, it will become very easy for you to extend the Elementor the way you want.<\/p>\n\n\n\n<p>Elementor also provides hooks if you want to add control or sections. But it doesn&#8217;t give you much flexibility in terms of adding the controls at specific locations. So I don&#8217;t prefer this option.<\/p>\n\n\n\n<p>I hope you will be much confident in recreating an Elementor Widgets as per your design requirements.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There will always be a case in which the widget or the addons you are using does not match your required design.<\/p>\n","protected":false},"author":2,"featured_media":1130,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[30],"class_list":["post-1097","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-plugin","tag-elementor"],"blocksy_meta":{"page_structure_type":"default","page_enable_vertical_spacing":"yes","has_hero_section":"default","hero_section":"type-1","hero_alignment1":"left","hero_alignment2":"center","hero_height":"230px","page_title_bg_type":"color","e3ce1123623a09f46d6d8a99e1e83ceb":"","custom_hero_background":{"attachment_id":null},"parallax":{"desktop":false,"tablet":false,"mobile":false},"c2b6795c38cdd8f37b47334ce6a8e55d":"","single_meta_elements":{"author":true,"date":true,"categories":true,"comments":true,"updated":false,"tags":false},"has_meta_label":"yes","date_format_source":"custom","single_meta_date_format":"M j, Y","cfbb499e9f4da300308a22150c103075":"","page_excerpt_visibility":{"desktop":true,"tablet":true,"mobile":false},"pageTitleFont":{"family":"Default","variation":"Default","size":{"desktop":"32px","tablet":"30px","mobile":"25px"},"line-height":"1.3","letter-spacing":"CT_CSS_SKIP_RULE","text-transform":"CT_CSS_SKIP_RULE","text-decoration":"CT_CSS_SKIP_RULE"},"pageTitleFontColor":{"default":{"color":"var(--paletteColor4)"}},"pageMetaFont":{"family":"Default","variation":"n6","size":{"desktop":"12px","tablet":"12px","mobile":"12px"},"line-height":"1.3","letter-spacing":"CT_CSS_SKIP_RULE","text-transform":"uppercase","text-decoration":"CT_CSS_SKIP_RULE"},"pageMetaFontColor":{"default":{"color":"CT_CSS_SKIP_RULEDEFAULT"},"hover":{"color":"CT_CSS_SKIP_RULEDEFAULT"}},"pageExcerptFont":{"family":"Default","variation":"n5","size":"CT_CSS_SKIP_RULE","line-height":"CT_CSS_SKIP_RULE.65","letter-spacing":"CT_CSS_SKIP_RULE","text-transform":"CT_CSS_SKIP_RULE","text-decoration":"CT_CSS_SKIP_RULE"},"pageExcerptColor":{"default":{"color":"CT_CSS_SKIP_RULEDEFAULT"}},"pageTitleOverlay":{"default":{"color":"rgba(41, 51, 60, 0.2)"}},"pageTitleBackground":{"default":{"color":"#EDEFF2"}},"39dd1c7074e7cd6de642cb084f513a3c":"","675886beb55c3d4128203487c89d4ecf":"","3039061f9794da8df1d4945fdcbc9a1f":"","7d809a38443c6aedd3284567d57973fd":"","97f91918b8b187cff4b6a9c386a7baa9":"","26fbecd6c1c5b2cda7ecd362060325a1":"","a50c70531d3e361c5fb990ec42fb0b42":"","bdfec7be28df016b80925fa0fbc404ee":"","970a4d67505db1bea0722997314857cb":"","ef9d9b6a72577ee41f905de8607c4eae":"","02a80868de41eaad51b897af20f25f01":"","72c2a3cdb3a1e72c6139a49ebab17678":""},"_links":{"self":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1097","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/comments?post=1097"}],"version-history":[{"count":10,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1097\/revisions"}],"predecessor-version":[{"id":1131,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/posts\/1097\/revisions\/1131"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/media\/1130"}],"wp:attachment":[{"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/media?parent=1097"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/categories?post=1097"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pixelstudio.id\/blog\/wp-json\/wp\/v2\/tags?post=1097"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}