Request Quote

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

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.1.*
So, this process is for Magento version > 2.1.*

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

1. Create a registration.php file inside Vendor_Module

<?php
/**
* Webkul Software.
* @category Webkul
* @package Vendor_Module
* @author Webkul
* @copyright Copyright (c) 2010-2019 Webkul Software Private Limited (https://webkul.com)
* @license https://store.webkul.com/license.html*/

\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
"Vendor_Module",
__DIR__);

2. Create module.xml file inside Vendor_Module/etc folder.

<?xml version=”1.0″?>
<!–
/**
* Webkul Software.
*
* @category Webkul
* @package Vendor_Module
* @author Webkul
* @copyright Copyright (c) 2010-2019 Webkul Software Private Limited (https://webkul.com)
* @license https://store.webkul.com/license.html
*/
–>
<config xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd”>
<module name=”Vendor_Module” setup_version=”1.0.0″>
</module>
</config>

3. Create routes.xml file inside Vendor_Module/etc/frontend.

<?xml version=”1.0″?>
<!–
/**
* Webkul Software.
*
* @category Webkul
* @package Vendor_Module
* @author Webkul
* @copyright Copyright (c) 2010-2018 Webkul Software Private Limited (https://webkul.com)
* @license https://store.webkul.com/license.html
*/
–>
<config xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”urn:magento:framework:App/etc/routes.xsd”>
<router id=”standard”>
<route id=”routename” frontName=”routename”>
<module name=”Vendor_Module” />
</route>
</router>
</config>

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

<?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();
}
}

5. 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;
}
}

6. 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>

7. 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;
}
}

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

<?xml version=”1.0″?>
<!–
/**
* Webkul Software.
*
* @category Webkul
* @package Vendor_Module
* @author Webkul
* @copyright Copyright (c) 2010-2018 Webkul Software Private Limited (https://webkul.com)
* @license https://store.webkul.com/license.html
*/
–>
<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 🙂

Custom product Collection

. . .

Comment

Add Your Comment

Be the first to comment.

css.php
Hire Us!
Brief us about your requirements and we'll get back to you.
Woo! Hooy!
We have just recieved your project brief and our expert will contact you shortly.
Send Again
Close