Creating a Custom Widget in Magento 2
Creating a Custom Widget in Magento 2

Creating a Custom Widget in Magento 2

Published April 28, 2017 in Development
Magento 2: Dynamic Store Configuration Fields
Dynamic Store Configuration Fields
April 3, 2017
How to Increase Organic Traffic with Keyword Research
August 2, 2017

Creating a custom widget in Magento 2

It’s not common that you need a custom widget in Magento 2. They offer a fairly wide array of well-made widgets with easy-to-use customization. However, sometimes you need to change the functionality of a widget or increase the selection of customization options, and in order to do this, you need to create your own. In this article, we will be looking at how to create a widget that extends the functionality of a core widget. We will be extending the functionality of the “Catalog Products List” widget so that we can change how the products are ordered.

Create the extension

Before we can create a widget, we need somewhere to put it. For this, we need a vendor folder in app\code and a module folder in the vendor folder. For the sake of this article, I will be using app\code\ClassyLlama\SortedProductsWidget. In the module folder we need two files: registration.php and etc\module.xml.



As this is somewhat of an advanced tutorial, I assume that you know why these files need to be present and will not be going in-depth with their code. The only thing I will mention is the <sequence> tag in etc\module.xml, which is basically telling Magento to load Magento_CatalogWidget before our extension.



Now that we’ve created the extension, we can start building the widget. In order to create the layout of the widget, we must create etc\widget.xml.


You can see that we create a <widget> inside a <widgets> tag. The <widget> tag contains parameters for our widget configuration. The id for our widget is a specific name that you want to use for your widget. It can be anything, but for this tutorial we called it classyllama_products_list. The class is a block that we will create soon; it controls how the widget actually functions (we will be extending the functionality of the Magento\CatalogWidget\Block\Product\ProductsList block). The placeholder_image is just an image that shows in the WYSIWYG editor of the backend of Magento. It’s not necessary but adds a nice touch when viewing the WYSIWYG.

Inside the widget, you can see that we’ve listed parameters, which are the inputs that we need from the WYSIWYG editor. Each of these parameters having a name, type, required, and visible option. The name should be logical, as you will need to reference it in the widget block. Since we are extending the base Magento block, we have used the same names as the ones in the core product list widget. The type is simply what type of input you want to use in the backend when configuring the widget. visible controls the option’s visibility in the form when configuring. Inside each parameter tag, there’s a <label> tag that sets a label for the option. You’ll also notice that some parameters have a <depends> tag. This states that the given parameter will only appear when the parameter specified in the depends tag has the value that is set in this tag. Some parameters also have a <value> tag that sets the default value for the given parameter. Finally, the parameters that have their type as select (or anything that requires predetermined options) need one of two things. They need either a source_model defined like our products_sort_by and products_sort_order parameters or an <options> tag like our template parameter.

Creating the Block

Now that we understand the widget.xml file, we can create our ‘ProductsList.php’ file. This file should be located at Block\Product\ProductsList.php.


As I mentioned earlier, we are extending the \Magento\CatalogWidget\Block\Product\ProductsList.php file, so we don’t need to rewrite any methods that are already written for us. However, we did rewrite the createCollection() function and added two new functions. The createCollection() function didn’t change much, we just set the order of the collection using setOrder(). This function takes two parameters: a string containing what you want to sort by, and a string containing the order in which you want to sort (ascending or descending).

If you look at one of our new functions, we can see what exactly they’re doing.

The first thing this method does is check whether the user has set the widget parameter with the name products_sort_by. If not, then it sets products_sort_by to the default value that we defined earlier in the code. Finally, it returns the data that is associated with products_sort_by.

Creating the Models

Now that we’ve created our widget’s layout and its block, we can create our models. These models are the files that are assigned as source_model for our widget parameters in the layout. These files are simple, their only job being to return an array of options. You will need to create two model files for this tutorial: Model\SortBy.php and Model\SortOrder.php.



These files only have one method each: toOptionArray(). This returns an array of the possible options for your widget parameter. Each option has a value, which is what the value of an option is, and a label, which is what the user sees when viewing the options.


Now that we’ve created our widget, we can test it and make sure everything works as it should. We’re just going to add our widget to the homepage, so navigate through the backend to the WYSIWYG for the homepage and add a widget. As you can see we’ve successfully selected our widget type and set our options.

widget options

Now that we’ve created and configured our extension, let’s go to the homepage and see if it works!

widget display

And it does! Congratulations, you’ve just created a custom widget in Magento 2!


  1. satria says:

    Hi, Thanks for the tutorial.
    Based on this example, how to add/display the left sidebar and the navigation?

  2. Smith says:

    Very helpful article Zach ! Good work.
    I was trying to implement this product widget into our magento 2 installation. It was configured successfully. At store frontend products are shows well. However the pagination links are like, etc.. and pagination seems not working correctly. Could you please help to resolve this.

  3. Rohit Jaiswal says:

    You added the title of the widget, where is the title coming from while rendering on frontend?

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.

Most Recent PostsView all
October 15, 2021

Classy Llama Wins 2021 Comparably Awards for Best Perks&Benefits, Best Work-Life Balance

Classy Llama, Springfield’s only full-service eCommerce agency, has been placed on the top 50 list for’s Best Perks&Benefits Award, as well as their Best Work-Life […]
September 15, 2021

Classy Llama Awarded #3 Best Place to Work by Biz417

Springfield, MO — Classy Llama has been awarded the number 3 spot on the Biz417 Best Places to Work Top 20 for 2021.  This award is […]
September 13, 2021

2021 Instagram Changes: What you need to know for eCommerce Marketing

What’s Going On With Instagram in 2021? The Head of Instagram, Adam Mosseri, announced in summer 2021 that big changes are coming to the platform sometime […]