Skip to main content
public function __construct(
    \Magento\Framework\App\Action\Context $context,
    \Magento\Framework\View\Result\PageFactory $pageFactory,
    \Magento\Catalog\Model\Layer\Resolver $layerResolver

) { $this->layerResolver = $layerResolver; $this->pageFactory = $pageFactory; $this->context = $context; parent::__construct($context); }

public function execute() {
$date = new \Zend_Date(); $result = $this->pageFactory->create(); $this->layerResolver->create('search');

) {
    $this->layerResolver = $layerResolver;
    $this->pageFactory = $pageFactory;
    $this->context = $context;
    parent::__construct($context);
}

public function execute()
{        
    $date = new \Zend_Date();
    $result = $this->pageFactory->create();
    $this->layerResolver->create('search');

    $collection = $this->layerResolver->get()->getProductCollection();
    $collection->('special_price', ['gt'=>0],'left');
    $collection
         ->addAttributeToFilter(
            'special_from_date',
            [
                'or' => [
                    0 => [
                        'date' => true,
                        'to' => $date->get('YYYY-MM-dd').' 23:59:59'],
                    1 => [
                        'is' => new \Zend_Db_Expr('null')
                    ],
                ]
            ],
            'left'
        )->addAttributeToFilter(
            'special_to_date',
            [
                'or' => [
                    0 => [
                        'date' => true,
                        'from' =>  $date->get('YYYY-MM-dd').' 00:00:00'],
                    1 => [
                        'is' => new \Zend_Db_Expr('null')
                    ],
                ]
            ],
            'left'
        );
    $list = $result->getLayout()->getBlock('custom.products.list');
    $list->setProductCollection($collection);
    return $result;
}

} To To avoid problems with aggregations and buckets I use this:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <!-- To prepare the filterlist for our custom collection which would be passed to the left navigation we need below virtual types for our custom page navigation -->
    <virtualType name="customFilterList" type="Vendor\Module\Model\Layer\FilterList">
        <arguments>
            <argument name="filterableAttributes" xsi:type="object">Vendor\Module\Model\Layer\FilterableAttributeList</argument>
            <argument name="filters" xsi:type="array">
                <item name="attribute" xsi:type="string">Vendor\Module\Model\Layer\Filter\Attribute</item>
                <item name="category" xsi:type="string">Vendor\Module\Model\Layer\Filter\Category</item>
            </argument>
        </arguments>
    </virtualType>

    <!-- once the filter list virtual type is ready we can pass the same to our navigation , I have prepared the virtual type of the core navigation for my custom module and have passed the custom filter list to it -->
    <virtualType name="Vendor\Module\Block\Navigation\Custnavigation" type="Magento\LayeredNavigation\Block\Navigation">
        <arguments>
            <argument name="filterList" xsi:type="object">customFilterList</argument>
        </arguments>
    </virtualType>
</config>
Vendor/Module/Model/Layer/FilterableAttributeList.php

namespace Vendor\Module\Model\Layer; class FilterableAttributeList extends \Magento\Catalog\Model\Layer\Category\FilterableAttributeList { } VendorVendor/Module/Model/Layer/FilterableAttributeList.php

namespace Vendor\Module\Model\Layer;
class FilterableAttributeList extends \Magento\Catalog\Model\Layer\Category\FilterableAttributeList
{
}

Vendor/Module/Model/Layer/FilterList.php

namespace Vendor\Module\Model\Layer;
class FilterList extends \Magento\Catalog\Model\Layer\FilterList
{
}

namespace Vendor\Module\Model\Layer; class FilterList extends \Magento\Catalog\Model\Layer\FilterList { } VendorVendor/Module/Model/Layer/Filter/Attribute.php

namespace Vendor\Module\Model\Layer\Filter;

namespace Vendor\Module\Model\Layer\Filter;

class Attribute extends \Magento\Catalog\Model\Layer\Filter\Attribute
{
}

class Attribute extends \Magento\Catalog\Model\Layer\Filter\Attribute { } VendorVendor/Module/Model/Layer/Filter/Category.php

namespace Vendor\Module\Model\Layer\Filter;

namespace Vendor\Module\Model\Layer\Filter;

class Category extends \Magento\CatalogSearch\Model\Layer\Filter\Category
{
}

class Category extends \Magento\CatalogSearch\Model\Layer\Filter\Category { } VendorVendor/Module/view/frontend/layout/custompage_index_index.xml

product_list_toolbarVendor/Module/Block/Product/CustomList.php

namespace Vendor\Module\Block\Product;

use Magento\Catalog\Block\Product\ListProduct; use Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection;

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left">
    <body>
        <attribute name="class" value="page-with-filter"/>
        <referenceContainer name="sidebar.main">
            <block class="Vendor\Module\Block\Navigation\Custnavigation" name="catalog.leftnav" before="-" template="Magento_LayeredNavigation::layer/view.phtml">
                <block class="Magento\LayeredNavigation\Block\Navigation\State" name="catalog.navigation.state" as="state" />
                <block class="Magento\LayeredNavigation\Block\Navigation\FilterRenderer" name="catalog.navigation.renderer" as="renderer" template="Magento_LayeredNavigation::layer/filter.phtml"/>
            </block>
        </referenceContainer>
        <referenceContainer name="content">
            <block class="Vendor\Module\Block\Product\CustomList" 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\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>

class CustomList extends ListProduct { public function getLoadedProductCollection() { return $this->_productCollection; }Vendor/Module/Block/Product/CustomList.php

namespace Vendor\Module\Block\Product;

use Magento\Catalog\Block\Product\ListProduct;
use Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection;

class CustomList extends ListProduct
{
    public function getLoadedProductCollection()
    {
        return $this->_productCollection;
    }

    public function setProductCollection(AbstractCollection $collection)
    {
        $this->_productCollection = $collection;
    }
}

} This This will give you filtered collection on custom page via available special price today. You will have attributes to filter but i still cant get category filter to work properly ( count number for products in collection and layered navigation doesnt match and not all categories are displayed ). If anyone can provide answer on how to make category filter to work with this or other solutions please help.

Most of this code was found here on StackexchangeStack Exchange in questions with layered-navigation tag.

public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $pageFactory,
\Magento\Catalog\Model\Layer\Resolver $layerResolver

) { $this->layerResolver = $layerResolver; $this->pageFactory = $pageFactory; $this->context = $context; parent::__construct($context); }

public function execute() {
$date = new \Zend_Date(); $result = $this->pageFactory->create(); $this->layerResolver->create('search');

$collection = $this->layerResolver->get()->getProductCollection();
$collection->('special_price', ['gt'=>0],'left');
$collection
     ->addAttributeToFilter(
        'special_from_date',
        [
            'or' => [
                0 => [
                    'date' => true,
                    'to' => $date->get('YYYY-MM-dd').' 23:59:59'],
                1 => [
                    'is' => new \Zend_Db_Expr('null')
                ],
            ]
        ],
        'left'
    )->addAttributeToFilter(
        'special_to_date',
        [
            'or' => [
                0 => [
                    'date' => true,
                    'from' =>  $date->get('YYYY-MM-dd').' 00:00:00'],
                1 => [
                    'is' => new \Zend_Db_Expr('null')
                ],
            ]
        ],
        'left'
    );
$list = $result->getLayout()->getBlock('custom.products.list');
$list->setProductCollection($collection);
return $result;

} To avoid problems with aggregations and buckets I use this:

<!-- To prepare the filterlist for our custom collection which would be passed to the left navigation we need below virtual types for our custom page navigation -->
<virtualType name="customFilterList" type="Vendor\Module\Model\Layer\FilterList">
    <arguments>
        <argument name="filterableAttributes" xsi:type="object">Vendor\Module\Model\Layer\FilterableAttributeList</argument>
        <argument name="filters" xsi:type="array">
            <item name="attribute" xsi:type="string">Vendor\Module\Model\Layer\Filter\Attribute</item>
            <item name="category" xsi:type="string">Vendor\Module\Model\Layer\Filter\Category</item>
        </argument>
    </arguments>
</virtualType>

<!-- once the filter list virtual type is ready we can pass the same to our navigation , I have prepared the virtual type of the core navigation for my custom module and have passed the custom filter list to it -->
<virtualType name="Vendor\Module\Block\Navigation\Custnavigation" type="Magento\LayeredNavigation\Block\Navigation">
    <arguments>
        <argument name="filterList" xsi:type="object">customFilterList</argument>
    </arguments>
</virtualType>
Vendor/Module/Model/Layer/FilterableAttributeList.php

namespace Vendor\Module\Model\Layer; class FilterableAttributeList extends \Magento\Catalog\Model\Layer\Category\FilterableAttributeList { } Vendor/Module/Model/Layer/FilterList.php

namespace Vendor\Module\Model\Layer; class FilterList extends \Magento\Catalog\Model\Layer\FilterList { } Vendor/Module/Model/Layer/Filter/Attribute.php

namespace Vendor\Module\Model\Layer\Filter;

class Attribute extends \Magento\Catalog\Model\Layer\Filter\Attribute { } Vendor/Module/Model/Layer/Filter/Category.php

namespace Vendor\Module\Model\Layer\Filter;

class Category extends \Magento\CatalogSearch\Model\Layer\Filter\Category { } Vendor/Module/view/frontend/layout/custompage_index_index.xml

product_list_toolbarVendor/Module/Block/Product/CustomList.php

namespace Vendor\Module\Block\Product;

use Magento\Catalog\Block\Product\ListProduct; use Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection;

class CustomList extends ListProduct { public function getLoadedProductCollection() { return $this->_productCollection; }

public function setProductCollection(AbstractCollection $collection)
{
    $this->_productCollection = $collection;
}

} This will give you filtered collection on custom page via available special price today. You will have attributes to filter but i still cant get category filter to work properly ( count number for products in collection and layered navigation doesnt match and not all categories are displayed ). If anyone can provide answer on how to make category filter to work with this or other solutions please help.

Most of this code was found here on Stackexchange in questions with layered-navigation tag.

public function __construct(
    \Magento\Framework\App\Action\Context $context,
    \Magento\Framework\View\Result\PageFactory $pageFactory,
    \Magento\Catalog\Model\Layer\Resolver $layerResolver
) {
    $this->layerResolver = $layerResolver;
    $this->pageFactory = $pageFactory;
    $this->context = $context;
    parent::__construct($context);
}

public function execute()
{        
    $date = new \Zend_Date();
    $result = $this->pageFactory->create();
    $this->layerResolver->create('search');

    $collection = $this->layerResolver->get()->getProductCollection();
    $collection->('special_price', ['gt'=>0],'left');
    $collection
         ->addAttributeToFilter(
            'special_from_date',
            [
                'or' => [
                    0 => [
                        'date' => true,
                        'to' => $date->get('YYYY-MM-dd').' 23:59:59'],
                    1 => [
                        'is' => new \Zend_Db_Expr('null')
                    ],
                ]
            ],
            'left'
        )->addAttributeToFilter(
            'special_to_date',
            [
                'or' => [
                    0 => [
                        'date' => true,
                        'from' =>  $date->get('YYYY-MM-dd').' 00:00:00'],
                    1 => [
                        'is' => new \Zend_Db_Expr('null')
                    ],
                ]
            ],
            'left'
        );
    $list = $result->getLayout()->getBlock('custom.products.list');
    $list->setProductCollection($collection);
    return $result;
}

To avoid problems with aggregations and buckets I use this:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <!-- To prepare the filterlist for our custom collection which would be passed to the left navigation we need below virtual types for our custom page navigation -->
    <virtualType name="customFilterList" type="Vendor\Module\Model\Layer\FilterList">
        <arguments>
            <argument name="filterableAttributes" xsi:type="object">Vendor\Module\Model\Layer\FilterableAttributeList</argument>
            <argument name="filters" xsi:type="array">
                <item name="attribute" xsi:type="string">Vendor\Module\Model\Layer\Filter\Attribute</item>
                <item name="category" xsi:type="string">Vendor\Module\Model\Layer\Filter\Category</item>
            </argument>
        </arguments>
    </virtualType>

    <!-- once the filter list virtual type is ready we can pass the same to our navigation , I have prepared the virtual type of the core navigation for my custom module and have passed the custom filter list to it -->
    <virtualType name="Vendor\Module\Block\Navigation\Custnavigation" type="Magento\LayeredNavigation\Block\Navigation">
        <arguments>
            <argument name="filterList" xsi:type="object">customFilterList</argument>
        </arguments>
    </virtualType>
</config>

Vendor/Module/Model/Layer/FilterableAttributeList.php

namespace Vendor\Module\Model\Layer;
class FilterableAttributeList extends \Magento\Catalog\Model\Layer\Category\FilterableAttributeList
{
}

Vendor/Module/Model/Layer/FilterList.php

namespace Vendor\Module\Model\Layer;
class FilterList extends \Magento\Catalog\Model\Layer\FilterList
{
}

Vendor/Module/Model/Layer/Filter/Attribute.php

namespace Vendor\Module\Model\Layer\Filter;

class Attribute extends \Magento\Catalog\Model\Layer\Filter\Attribute
{
}

Vendor/Module/Model/Layer/Filter/Category.php

namespace Vendor\Module\Model\Layer\Filter;

class Category extends \Magento\CatalogSearch\Model\Layer\Filter\Category
{
}

Vendor/Module/view/frontend/layout/custompage_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left">
    <body>
        <attribute name="class" value="page-with-filter"/>
        <referenceContainer name="sidebar.main">
            <block class="Vendor\Module\Block\Navigation\Custnavigation" name="catalog.leftnav" before="-" template="Magento_LayeredNavigation::layer/view.phtml">
                <block class="Magento\LayeredNavigation\Block\Navigation\State" name="catalog.navigation.state" as="state" />
                <block class="Magento\LayeredNavigation\Block\Navigation\FilterRenderer" name="catalog.navigation.renderer" as="renderer" template="Magento_LayeredNavigation::layer/filter.phtml"/>
            </block>
        </referenceContainer>
        <referenceContainer name="content">
            <block class="Vendor\Module\Block\Product\CustomList" 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\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>

Vendor/Module/Block/Product/CustomList.php

namespace Vendor\Module\Block\Product;

use Magento\Catalog\Block\Product\ListProduct;
use Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection;

class CustomList extends ListProduct
{
    public function getLoadedProductCollection()
    {
        return $this->_productCollection;
    }

    public function setProductCollection(AbstractCollection $collection)
    {
        $this->_productCollection = $collection;
    }
}

This will give you filtered collection on custom page via available special price today.

Most of this code was found here on Stack Exchange in questions with layered-navigation tag.

Source Link

I was able to get product collection by using layerResolver like this:

Vendor/Module/Controller/Index/Index.php

public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $pageFactory,
\Magento\Catalog\Model\Layer\Resolver $layerResolver

) { $this->layerResolver = $layerResolver; $this->pageFactory = $pageFactory; $this->context = $context; parent::__construct($context); }

public function execute() {
$date = new \Zend_Date(); $result = $this->pageFactory->create(); $this->layerResolver->create('search');

$collection = $this->layerResolver->get()->getProductCollection();
$collection->('special_price', ['gt'=>0],'left');
$collection
     ->addAttributeToFilter(
        'special_from_date',
        [
            'or' => [
                0 => [
                    'date' => true,
                    'to' => $date->get('YYYY-MM-dd').' 23:59:59'],
                1 => [
                    'is' => new \Zend_Db_Expr('null')
                ],
            ]
        ],
        'left'
    )->addAttributeToFilter(
        'special_to_date',
        [
            'or' => [
                0 => [
                    'date' => true,
                    'from' =>  $date->get('YYYY-MM-dd').' 00:00:00'],
                1 => [
                    'is' => new \Zend_Db_Expr('null')
                ],
            ]
        ],
        'left'
    );
$list = $result->getLayout()->getBlock('custom.products.list');
$list->setProductCollection($collection);
return $result;

} To avoid problems with aggregations and buckets I use this:

Vendor/Module/etc/di.xml

<!-- To prepare the filterlist for our custom collection which would be passed to the left navigation we need below virtual types for our custom page navigation -->
<virtualType name="customFilterList" type="Vendor\Module\Model\Layer\FilterList">
    <arguments>
        <argument name="filterableAttributes" xsi:type="object">Vendor\Module\Model\Layer\FilterableAttributeList</argument>
        <argument name="filters" xsi:type="array">
            <item name="attribute" xsi:type="string">Vendor\Module\Model\Layer\Filter\Attribute</item>
            <item name="category" xsi:type="string">Vendor\Module\Model\Layer\Filter\Category</item>
        </argument>
    </arguments>
</virtualType>

<!-- once the filter list virtual type is ready we can pass the same to our navigation , I have prepared the virtual type of the core navigation for my custom module and have passed the custom filter list to it -->
<virtualType name="Vendor\Module\Block\Navigation\Custnavigation" type="Magento\LayeredNavigation\Block\Navigation">
    <arguments>
        <argument name="filterList" xsi:type="object">customFilterList</argument>
    </arguments>
</virtualType>
Vendor/Module/Model/Layer/FilterableAttributeList.php

namespace Vendor\Module\Model\Layer; class FilterableAttributeList extends \Magento\Catalog\Model\Layer\Category\FilterableAttributeList { } Vendor/Module/Model/Layer/FilterList.php

namespace Vendor\Module\Model\Layer; class FilterList extends \Magento\Catalog\Model\Layer\FilterList { } Vendor/Module/Model/Layer/Filter/Attribute.php

namespace Vendor\Module\Model\Layer\Filter;

class Attribute extends \Magento\Catalog\Model\Layer\Filter\Attribute { } Vendor/Module/Model/Layer/Filter/Category.php

namespace Vendor\Module\Model\Layer\Filter;

class Category extends \Magento\CatalogSearch\Model\Layer\Filter\Category { } Vendor/Module/view/frontend/layout/custompage_index_index.xml

product_list_toolbar Vendor/Module/Block/Product/CustomList.php

namespace Vendor\Module\Block\Product;

use Magento\Catalog\Block\Product\ListProduct; use Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection;

class CustomList extends ListProduct { public function getLoadedProductCollection() { return $this->_productCollection; }

public function setProductCollection(AbstractCollection $collection)
{
    $this->_productCollection = $collection;
}

} This will give you filtered collection on custom page via available special price today. You will have attributes to filter but i still cant get category filter to work properly ( count number for products in collection and layered navigation doesnt match and not all categories are displayed ). If anyone can provide answer on how to make category filter to work with this or other solutions please help.

Most of this code was found here on Stackexchange in questions with layered-navigation tag.