Magento 2 Widgets Tutorial
Widgets are a great functionality of Magento, which is unfortunately often brushed aside by developers. This is partly because of a lack of resources which would in simple terms explain their usage and implementation to inexperienced coders.
Widgets combine the simplicity of using CMS blocks with the extensiveness of templates. They allow us to leave the configuration of a given element up to the backend user, without cluttering the database with redundant markup. For example, if the user wants to choose the location of the Call to Action button on the home page hero banner it is far easier for them to simply choose an option from a dropdown with a list of possible locations, than to struggle with markup and the WYSIWYG editor.
Widgets are best described as configurable instances of blocks (which are a part of modules).
Following the assumption that it is best to learn by doing, we will create a small widget today, which will display an image from the unsplash.com database on a page. The user adding the image will have an ability to select the category from which the image is to be pulled. This simple example will allow us to trace the process of adding and configuring the widget without delving into the complicated logic and templating.
We will begin with adding a module:
1
2
3
4
5
6
7
//app/code/Magently/UnsplashWidget/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Magently_UnsplashWidget',
__DIR__
);
1
2
3
4
5
6
//app/code/Magently/UnsplashWidget/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Magently_UnsplashWidget" setup_version="1.0.0">
</module>
</config>
Now that the module is declared, it is time to add a block:
1
2
3
4
5
6
7
8
9
10
11
12
//app/code/Magently/UnsplashWidget/Block/Widget/Image.php
<?php
namespace Magently\UnsplashWidget\Block\Widget;
class Image extends \Magento\Framework\View\Element\Template implements \Magento\Widget\Block\BlockInterface
{
protected function _construct()
{
parent::_construct();
$this->setTemplate('widget/unsplash_image.phtml');
}
}
As you can see, the only thing we did here is set a template for our widget. However, there is nothing that would prevent us from giving the user a choice of several templates. Now we can handle the configuration of the widget. Here we can set the ID for the widget, the class of the block which the widget will use, and its name which will be visible in the backend. Additionally, in the same file we set the parameters which the widget will take. We are interested specifically in the category from which the image is to be pulled:
1
2
3
4
5
6
7
8
9
10
11
12
13
//app/code/Magently/UnsplashWidget/etc/widget.xml
<?xml version="1.0" encoding="UTF-8"?>
<widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Widget:etc/widget.xsd">
<widget id="magently_unsplashwidget" class="Magently\UnsplashWidget\Block\Widget\Image">
<label translate="true">Unsplash Image Widget</label>
<description>Plain image from specified category</description>
<parameters>
<parameter name="category" xsi:type="text" required="true" visible="true" sort_order="10">
<label translate="true">Category Name</label>
</parameter>
</parameters>
</widget>
</widgets>
The only thing left to do now is adding the template which will display the image:
1
2
3
4
5
6
7
//app/code/Magently/UnsplashWidget/view/frontend/templates/widget/unsplash_image.phtml
<?php
$category = $block->getData('category');
$image = '//source.unsplash.com/category/' . $category;
?>
<img src='<?php echo $image ?>' alt='<?php echo $category ?>'>
And that would be it. Now all that you have to do is run setup:upgrade, so that our new module is registered in the database, and add the widget where needed.