Magento 2: Add Custom “Sort By” Option Filter in Tool Bar

In the native Magento 2, the following three types of sorting options will be shown on the toolbar in the category page,

  • Sort by “Position”
  • Sort by “Product Name”
  • Sort by “Price”

But in some cases, you may want to add some more new option in the category toolbar like sorting products by created date (newest), best-selling products, etc. Adding new sort option in the category toolbar is not a difficult job, and here is the blog which helps you to customize the code with less amount of time.

In this blog, I am going to show the demo that how to add new sort option “Newest” in the toolbar of the category page. In order to add new sort option in Magento 2, we have to use the following two classes, Magento\Catalog\Model\Config & Magento\Catalog\Block\Product\ProductList\Toolbar

Step 1: Create a file named registration.php in the following file path,

File Path: app/code/BlogTreat/NewSorting/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'BlogTreat_NewSorting',
    __DIR__
);

Step 2: Create a file named module.xml in the following file path,

File Path: app/code/BlogTreat/NewSorting/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="BlogTreat_MyAttributeSet" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Catalog"/>
        </sequence>
    </module>
</config>

Step 3: Create a file named di.xml in the following file path, in this file, we have to add the plugin for the following native classes, Magento\Catalog\Model\Config & Magento\Catalog\Block\Product\ProductList\Toolbar

File Path: app/code/BlogTreat/NewSorting/etc/frontend/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\Config">
        <plugin name="BlogTreat_NewSorting::addNewSortOption" type="BlogTreat\NewSorting\Plugin\Model\Config" />
    </type>
    
    <type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
        <plugin name="BlogTreat_NewSorting::addNewFilterInToolbar" type="BlogTreat\NewSorting\Plugin\Product\ProductList\Toolbar" />
    </type>

</config>

Step 4: Create a file named Config.php in the following file path, in this file we have to customize the native code by plugin method to add our new sort option.

File Path: app/code/BlogTreat/NewSorting/Plugin/Model/Config.php

<?php
namespace BlogTreat\NewSorting\Plugin\Model;

class Config
{
	const NEWEST_SORT_BY = 'newest';

	/**
	 * Adding new sort option
	 *
	 * @param \Magento\Catalog\Model\Config $catalogConfig
	 * @param [] $result
	 * @return []
	 */
	public function afterGetAttributeUsedForSortByArray(
		\Magento\Catalog\Model\Config $subject, 
		$result
	) {
		return array_merge(
			$result, 
			[
				self::NEWEST_SORT_BY => __('Newest')
			]
		);
	}
}

Step 5: Finally, create a file named Toolbar.php in the following file path, in this file we have to customize the native code by plugin method to add our new sort option.

File Path: app/code/BlogTreat/NewSorting/Plugin/Product/ProductList/Toolbar.php

<?php
namespace BlogTreat\NewSorting\Plugin\Product\ProductList;

class Toolbar
{
	const NEWEST_SORT_BY = 'newest';

    /**
     * Around Plugin
     *
     * @param \Magento\Catalog\Block\Product\ProductList\Toolbar $subject
     * @param \Closure $proceed
     * @param \Magento\Framework\Data\Collection $collection
     * @return \Magento\Catalog\Block\Product\ProductList\Toolbar
     */
    public function aroundSetCollection(
        \Magento\Catalog\Block\Product\ProductList\Toolbar $subject,
        \Closure $proceed,
        $collection
    ) {
        $currentOrder = $subject->getCurrentOrder();
        $currentDirection = $subject->getCurrentDirection();
        $result = $proceed($collection);

        if ($currentOrder == self::NEWEST_SORT_BY) {
            if ($currentDirection == 'desc') {
                $subject->getCollection()->setOrder('created_at', 'desc');
            } 
            else {
                $subject->getCollection()->setOrder('created_at', 'asc');
            }
        }

        return $result;
    }
}

After completing the above steps run the below SSH command in your Magento 2 installed root directory,

php bin/magento setup:upgrade

Then, clear all the Magento cache and check the product list page on your store.

Note: We have tested the above code on Magento 2.3.

Hope this helps.

Leave a Reply

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