Reading list Switch to dark mode

    How To Implement Custom Attribute Filter In Custom Product Collection Page In Magento 2

    Updated 26 September 2021

    Sometimes, we need to add a custom attribute filter in the product list. but we can’t apply attribute filter directly, because when product collection loads there is an event ‘catalog_block_product_list_collection’ fired and an observer Magento\Review\Observer\CatalogBlockProductCollectionBeforeToHtmlObserver executes and it overrides the applied filter.

    So, to apply the custom attribute filter, we create a plugin of the execute method of CatalogBlockProductCollectionBeforeToHtmlObserver class.

    Note: We can directly add custom attribute filter in Magento version < 2.2.0
    So, this process is for Magento version > 2.2.*

    So, to add a custom attribute filter, follow the following steps one by one.

    1. Create CustomProductList.php file inside Vendor_Module/Block.

    Searching for an experienced
    Magento Company ?
    Find out More
    <?php
    namespace Vendor\Module\Block;
    use Magento\Catalog\Block\Product\ListProduct;
    use Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection;
    use Magento\Catalog\Api\CategoryRepositoryInterface;
    class CustomProductList extends ListProduct
    {
    public function __construct(
    \Magento\Catalog\Block\Product\Context $context,
    \Magento\Framework\Data\Helper\PostHelper $postDataHelper,
    \Magento\Catalog\Model\Layer\Resolver $layerResolver,
    CategoryRepositoryInterface $categoryRepository,
    \Magento\Framework\Url\Helper\Data $urlHelper
    ) {
    parent::__construct(
    $context,
    $postDataHelper,
    $layerResolver,
    $categoryRepository,
    $urlHelper
    );
    }
    /**
    * @return Magento\Eav\Model\Entity\Collection\AbstractCollection
    */
    protected function _getProductCollection()
    {
    return parent::_getProductCollection();
    }
    }

    2. Create Index.php file inside Vendor_Module/Controller/CustomProductList

    <?php
    namespace Vendor\Module\Controller\CustomProductList;
    use Magento\Framework\App\Action\Action;
    use Magento\Framework\App\Action\Context;
    use Magento\Framework\View\Result\PageFactory;
    class Index extends Action
    {
    /** @varPageFactory */
    protected $pageFactory;
    /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection */
    protected $productCollection;
    public function __construct(
    Context $context,
    PageFactory $pageFactory
    ) {
    $this->pageFactory = $pageFactory;
    parent::__construct($context);
    }
    public function execute()
    {
    $result = $this->pageFactory->create();
    return $result;
    }
    }

    3. Create layout file routename_controllername_actionname.xml (for example: demo_customproductlist_index.xml) file inside Vendor_Module/view/frontend.

    <page xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” layout=”2columns-left”
    xsi:noNamespaceSchemaLocation=”urn:magento:framework:View/Layout/etc/page_configuration.xsd”>
    <head>
    <title>Custom Product List</title>
    </head>
    <body>
    <referenceContainer name=”content”>
    <block class=”Vendor\Module\Block\CustomProductList” name=”custom.products.list” as=”product_list” template=”Magento_Catalog::product/list.phtml”>
    <container name=”category.product.list.additional” as=”additional” />
    <block class=”Magento\Framework\View\Element\RendererList” name=”category.product.type.details.renderers” as=”details.renderers”>
    <block class=”Magento\Framework\View\Element\Template” as=”default”/>
    </block>
    <block class=”Magento\Catalog\Block\Product\ProductList\Item\Container” name=”category.product.addto” as=”addto”>
    <block class=”Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare”
    name=”category.product.addto.compare”as=”compare”
    template=”Magento_Catalog::product/list/addto/compare.phtml”/>
    </block>
    <block class=”Magento\Catalog\Block\Product\ProductList\Toolbar” name=”product_list_toolbar” template=”Magento_Catalog::product/list/toolbar.phtml”>
    <block class=”Magento\Theme\Block\Html\Pager” name=”product_list_toolbar_pager”/>
    </block>
    <action method=”setToolbarBlockName”>
    <argument name=”name” xsi:type=”string”>product_list_toolbar</argument>
    </action>
    </block>
    </referenceContainer>
    </body>
    </page>

    4. Now, we will create the Plugin of CatalogBlockProductCollectionBeforeToHtmlObserver Class, in which we add the custom attribute filter. Here, we add a check for controller action name to avoid this filter in other product lists.

    <?php
    /**
    * Webkul Software.
    *
    * @category Webkul
    * @package Vendor_Module
    * @author Webkul
    * @copyright Copyright (c) Webkul Software Private Limited (https://webkul.com)
    * @license https://store.webkul.com/license.html
    */
    namespace Vendor\Module\Plugin;
    use \Magento\Framework\App\Helper\Context;
    class CatalogBlockProductCollectionBeforeToHtmlObserver
    {
    /**
    * Review model
    *
    * @var \Magento\Review\Model\ReviewFactory
    */
    protected $_reviewFactory;
    protected $_request;
    /**
    * @param Context $context
    * @param \Magento\Framework\App\RequestInterface $request
    * @param \Magento\Review\Model\ReviewFactory $reviewFactory
    */
    public function __construct(
    Context $context,
    \Magento\Framework\App\RequestInterface $request,
    \Magento\Review\Model\ReviewFactory $reviewFactory
    ) {
    $this->_reviewFactory = $reviewFactory;
    $this->_request = $request;
    }
    
    public function aroundExecute(
    \Magento\Review\Observer\CatalogBlockProductCollectionBeforeToHtmlObserver $subject,
    callable $proceed,
    \Magento\Framework\Event\Observer $observer
    ) {
    $productCollection = $observer->getEvent()->getCollection();
    if ($this->_request->getFullActionName() ==”demo_customproductlist_index”) {
    $productCollection->addAttributeToFilter(‘as_featured’, 1); //adding custom attribute filter in product collection
    }
    if ($productCollection instanceof \Magento\Framework\Data\Collection) {
    $productCollection->load();
    $this->_reviewFactory->create()->appendSummary($productCollection);
    }
    return $this;
    }
    }

    5. Finally, we mention this plugin in di.xml file.

    <?xml version=”1.0″?> 
    <config xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”urn:magento:framework:ObjectManager/etc/config.xsd”> 
         <type name=”Magento\Review\Observer\CatalogBlockProductCollectionBeforeToHtmlObserver”> <plugin name=”Vendor_Module::aroundExecute” type=”Vendor\Module\Plugin\CatalogBlockProductCollectionBeforeToHtmlObserver” sortOrder=”10″ /> 
        </type> 
    </config>

    Additionally, In above example, I have used the “as_featured” custom attribute. You can create your custom attribute as per your requirement using Setup files or from admin section.
    Thanks 🙂

    customproductlist

    Custom product Collection

    Previous Blog: Inspecting developer tools in iPad Device

    Next Blog: Profiler in Magento 2

    . . .

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    2 comments

  • highriskgateways
    Thanks for sharing a nice blog. Accept ACH payments with the secure, convenient and reliable method powered by HighRisk Gateways. ACH payment processing adds a flexible payment option in your business.
    https://bit.ly/2zKgRid
    • khushboo sahu (Moderator)
      Thanks 🙂
  • Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home