One feature of Magento that is not as often used as it should be are widgets. Widgets are configurable blocks that can be added to the content in wysiwyg editors in the admin. This gives us great possibilities to add rich content with the wysiwyg-editor without having to manually edit the HTML code. Because having your client edit the HTML code of your content is a recipe for disaster.
Widgets were already present in Magento 1, but in this article I’ll show you how to add widgets in Magento 2
Please note that we use the boilerplate module from the article ‘Creating a module in Magento 2‘ as the entry point for this article. If you never creating a block in Magento 2 before I also suggest to read this article first.
Declare your widget
The first thing you need to do, is let Magento know that you have widgets in the first place. The declaration of widgets is done in a file called widget.xml in the etc -folder of your module:
1 2 3 4 5 6 7 8 |
<?xml version="1.0"?> <widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Widget:etc/widget.xsd"> <widget id="example_widget" class="Gielberkers\Example\Block\Widget\Example"> <label translate="true">Example widget</label> <description translate="true">This is an example widget</description> </widget> </widgets> |
Widgets have 2 required parameters:
- label: This is the name of the widget as it appears in the dropdown when you select a widget.
- description: This is a short description that is shown as soon as you select your widget.
Create your widget class
Note that when declaring our widget we also provided a class: Gielberkers\Example\Block\Widget\Example . This is the class that Magento will use to render the widget. So let’s just take a look at that class shall we?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php namespace Gielberkers\Example\Block\Widget; use Magento\Framework\View\Element\Template; use Magento\Widget\Block\BlockInterface; class Example extends Template implements BlockInterface { /** * @return string */ public function _toHtml() { return '<p class="hello">Hello world!</p>'; } } |
Now that we created our declaration and our class, we can now …
Use your widget in the Wysiwyg editor
If you didn’t know already how to implement a widget with the wysiwyg-editor, let me show you again:
In the wysiwyg-editor, there is a small little button on the upper-left corner. Actually, it’s the second button (the first one is for variables):
When you click on this button, a panel appears in which you can select your widget:
That’s it! Insert the widget, save your page (or static block) and take a peek at the frontend. It’s pure magic.
Adding parameters to your widget
It is also possible to add parameters to your widget. This way, you can give your clients means to customise the widget:
1 2 3 4 5 6 7 8 9 10 |
<widget id="example_widget" class="Gielberkers\Example\Block\Widget\Example"> <label translate="true">Example widget</label> <description translate="true">This is an example widget</description> <parameters> <parameter name="name" xsi:type="text" visible="true" sort_order="0"> <label translate="true">Name</label> <description translate="true">Please enter a name</description> </parameter> </parameters> </widget> |
Now, if you now go back to the wysiwyg-editor and edit the (or add a new) widget, you’ll see that we’ve created an input field for our user:
We can access the data inside our widget class by using Magento’s magic methods:
1 2 3 4 |
public function _toHtml() { return '<p class="hello">Hello ' . $this->getName() . '</p>'; } |
Edit the widget, save the page, and take a peek at the frontend. Pure magic!
Different type of widget parameters
Not that we only created a parameter of the type ‘text’. Needless to say there are more parameters than just that. Some examples:
- select, for a dropdown
- multiselect, to select multiple options at once
Source models
One cool feature you can use in your widgets are source models. You can use source models to provide options of a ‘select’-parameter type. Just look at the following example of a parameter:
1 2 3 4 5 |
<parameter name="enabled" xsi:type="select" visible="true" sort_order="1" source_model="Magento\Config\Model\Config\Source\Yesno"> <label translate="true">Enabled</label> <description translate="true">Is this example enabled?</description> </parameter> |
This parameter uses the source model Magento\Config\Model\Config\Source\Yesno . Let’s take a look at this class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
namespace Magento\Config\Model\Config\Source; class Yesno implements \Magento\Framework\Option\ArrayInterface { /** * Options getter * * @return array */ public function toOptionArray() { return [['value' => 1, 'label' => __('Yes')], ['value' => 0, 'label' => __('No')]]; } /** * Get options in "key-value" format * * @return array */ public function toArray() { return [0 => __('No'), 1 => __('Yes')]; } } |
The key function here is toOptionArray() . This method returns an array that is used to populate the <select> -attribute:
There are a lot of source models you can use throughout Magento, just look in any given module if there is a Model\Config\Source -folder, and you’ll see there are a lot of source models out of the box that you can use! But you can also write your own source model of course:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
namespace Gielberkers\Example\Model\Config\Source; class Example implements \Magento\Framework\Option\ArrayInterface { /** * Options getter * * @return array */ public function toOptionArray() { return [ ['value' => 'foo', 'label' => __('Foo')], ['value' => 'bar', 'label' => __('Bar')] ]; } /** * Get options in "key-value" format * * @return array */ public function toArray() { return ['foo' => __('Foo'), 'bar' => __('Bar')]; } } |
Use it in your widget.xml:
1 2 3 4 5 |
<parameter name="example" xsi:type="select" visible="true" sort_order="1" source_model="Gielberkers\Example\Model\Config\Source\Example"> <label translate="true">Example</label> <description translate="true">The example value</description> </parameter> |
Needless to say, this is how it is rendered in the admin:
And you can use it in your block class by calling $this->getExample() .
Dependencies
You can also set field dependencies in widgets. This means that one field may only be visible if another field has a certain value. You declare these in the widget.xml file. Here’s an example that shows a category picker depending on another dropdown:
1 2 3 4 5 6 7 8 9 10 11 12 |
<parameter name="choose_category" xsi:type="select" visible="true" sort_order="1" source_model="Magento\Config\Model\Config\Source\Yesno"> <label translate="true">Choose Category</label> <description translate="true">Do you want to choose a category?</description> </parameter> <parameter name="id_path" xsi:type="select" visible="true" sort_order="1" source_model="Magento\Catalog\Model\Config\Source\Category"> <label translate="true">Category</label> <depends> <parameter name="choose_category" value="1"/> </depends> </parameter> |
Now, the thing that does the magic in this widget is the following line:
1 2 3 |
<depends> <parameter name="choose_category" value="1"/> </depends> |
What it says is: “If the parameter ‘choose_category’ has the value ‘1’ then make this field visible, hide otherwise.”. This can be seen when you put it to work:
This is of course a great way to simplify some of the more complex options of your widget, so that it’s better manageable.
This post is part of the series Magento 2 Development from Scratch.
Visitors give this article an average rating of 3.9 out of 5.
How would you rate this article?
★ ★ ★ ★ ★
You might want to look in the “template” node as well, it gives you the power of using different templates within one widget. When using it in a responsive theme, for example, this might come in handy if you need different markup for mobile and / or desktop.
Thanks for the tip! I’ll look into it!