Magento – magento 2 layer navigation in custom collection page and toolbar

layered-navigationmagento2

I want to call layer navigation in my custom page

<?php

namespace MPS\Allproduct\Block\Index;

use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Model\Category;
use Magento\Catalog\Block\Product\AbstractProduct;
use Magento\Catalog\Model\Product;
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\DataObject\IdentityInterface;
use Magento\Customer\Model\Context as CustomerContext;

class Index extends \Magento\Framework\View\Element\Template {

    protected $urlHelper;
    public function __construct(
        \Magento\Directory\Model\Currency $currency,       
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,  
        \Magento\Catalog\Block\Product\Context $context,
        \Magento\Framework\Data\Helper\PostHelper $postDataHelper,
        \Magento\Catalog\Model\Layer\Resolver $layerResolver,
        CategoryRepositoryInterface $categoryRepository,   
        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
        \Magento\Framework\Url\Helper\Data $urlHelper,
        \Magento\Framework\Data\Form\FormKey $formKey,

        array $data = []
    )
    {  
        $this->_categoryFactory = $categoryFactory;
        $this->_currency = $currency;
        $this->_catalogLayer = $layerResolver->get();
        $this->_postDataHelper = $postDataHelper;
        $this->categoryRepository = $categoryRepository;
        $this->urlHelper = $urlHelper;
        $this->_productCollectionFactory = $productCollectionFactory;

        $this->formKey = $formKey;
        parent::__construct($context, $data);
    }




    public function getAddToCartPostParams(\Magento\Catalog\Model\Product $_product)
    {
        $url = $this->getAddToCartUrl($_product);
        return [
            'action' => $url,
            'data' => [
                'product' => $_product->getEntityId(),
                \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED =>
                    $this->urlHelper->getEncodedUrl($url),
            ]
        ];
    }

    public function getNewProductCollection()
    {
        $collection = $this->_productCollectionFactory->create();
        $collection->addAttributeToSelect('*');
        /*$collection->setPageSize(4);*/

        $collection->setOrder('entity_id','DESC');

        return $collection;

    }
    public function getFormKey()
    {
        return $this->formKey->getFormKey();
    }
}

xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">

    <head>
        <title>Titlename</title>

    </head> 

    <body>


        <referenceContainer name="sidebar.main">
            <block class="MPS\Allproduct\Block\Index\Sidebar" name="allproduct_index_sidebar" before="-" template="MPS_Allproduct::allproduct_index_sidebar.phtml"/>
        </referenceContainer>

        <referenceContainer name="content">
            <block class="MPS\Allproduct\Block\Index\Index" name="allproduct_index_index" template="MPS_Allproduct::allproduct_index_index.phtml"/>
        </referenceContainer>


    </body>
</page>

How to achieve this?

Best Answer

I successfully applied my custom product collection on category page's layered navigation and toolbar.

For example, I am fetching the collection of those products whose price is less than 100.

Step 1: Add below code snippet

app/code/Vendor/Module/etc/di.xml

<?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\Catalog\Model\Layer">
        <plugin name="custom_product_model_layer" type="Vendor\Module\Plugin\Layer" />
    </type>

    <type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
        <plugin name="custom_product_toolbar" type="Vendor\Module\Plugin\Toolbar" />
    </type>

    <virtualType name="categoryFilterList" type="Magento\Catalog\Model\Layer\FilterList">
        <arguments>
            <argument name="filters" xsi:type="array">
                <item name="attribute" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Attribute</item>
                <item name="price" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Price</item>
                <item name="decimal" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Decimal</item>
                <item name="category" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Category</item>
            </argument>
        </arguments>
    </virtualType>

</config>

Step 2: Create plugin for product collection

app/code/Vendor/Module/Plugin/Layer.php

<?php
namespace Vendor\Module\Plugin;
class Layer
{
  public function aroundGetProductCollection(
    \Magento\Catalog\Model\Layer $subject,
    \Closure $proceed
  ) {

    $result = $proceed();
    $result->addAttributeToFilter('price', array('lt' => 100));
    return $result;
  }
}

Step 3: Create plugin for toolbar

app/code/Vendor/Module/Plugin/Toolbar.php

<?php
namespace Vendor\Module\Plugin;
class Toolbar
{

  protected $_objectManager;
  protected $request;

  public function __construct(
    \Magento\Framework\ObjectManagerInterface $objectmanager,
    \Magento\Framework\App\Request\Http $request
  ) {
    $this->_objectManager = $objectmanager;
    $this->request = $request;
  }

  public function aroundSetCollection(
    \Magento\Catalog\Block\Product\ProductList\Toolbar $subject,
    \Closure $proceed,
    $request
  ) {
    $result = $proceed($request);

    $this->_collection = $request;
    $category = $this->_objectManager->get('Magento\Framework\Registry')->registry('current_category');
    if($category)
    {
      $page = $this->request->getParam('p');
      if($page == '')
      {
        $page = 1;
      }
      $this->_collection->getCurPage();
      $this->_collection->setCurPage($page);  
    }
    else
    {
      $this->_collection->setCurPage($this->getCurrentPage());
    }

    return $result;
  }

}
Related Topic