Magento2 comes packed with a range of really useful widgets for displaying all sorts of content throughout your site. One widget we use time and again is the catalog product list widget, which allows you to use attribute conditions to fetch any products from the store you want to display on CMS pages or within containers on specific pages.
However, it can feel quite restricted out-of-the-box, as it is locked down to a single template and only 3 container positions;
- Main Content Area
- Main Content Top
- Main Content Bottom
Unlike most other widgets, which will inherit any available labelled containers from your theme/default layout, the Magento product list core widget defines it’s own container availability.
Here are some extracts from: /vendor/magento/module-catalog-widget/etc/widget.xml
Template declaration:
<parameter name="template" xsi:type="select" required="true" visible="true">
<label translate="true">Template</label>
<options>
<option name="default" value="Magento_CatalogWidget::product/widget/content/grid.phtml" selected="true">
<label translate="true">Products Grid Template</label>
</option>
</options>
</parameter>
Container declaration – note the template is also declared for each container position;
<containers>
<container name="content">
<template name="grid" value="default" />
</container>
<container name="content.top">
<template name="grid" value="default" />
</container>
<container name="content.bottom">
<template name="grid" value="default" />
</container>
</containers>
Add your own templates & containers...
To add your own templates and container positions, you need to create your own module and add file: NameSpace/Module/etc/widget.xml with the following content;
<?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_file.xsd">
<widget id="products_list">
<parameters>
<parameter name="template" xsi:type="select">
<options>
<option name="template-one" value="Magento_CatalogWidget::product/widget/content/grid.phtml">
<label>4 in a row</label>
</option>
<option name="template-two" value="Magento_CatalogWidget::product/widget/content/gridthree.phtml">
<label>3 in a row</label>
</option>
</options>
</parameter>
</parameters>
<containers>
<container name="content">
<template name="template-one" value="template-one" />
<template name="template-two" value="template-two" />
</container>
<container name="content.top">
<template name="template-one" value="template-one" />
<template name="template-two" value="template-two" />
</container>
<container name="content.bottom">
<template name="template-one" value="template-one" />
<template name="template-two" value="template-two" />
</container>
<container name="new.position">
<template name="template-one" value="template-one" />
<template name="template-two" value="template-two" />
</container>
</containers>
</widget>
</widgets>
We have now declared a second list widget template and added a new container, which is declared with name 'new.position' on our templates /Magento_Theme/layout/default.xml (don’t forget to give the container a label= attribute.
Happy coding!