I want to custom sort by option in category Filter. Currently Magento 2 provide Position , Product Name , Price And Sorting option to low to high. But i need to change all sorting option Like Price High to Low , Price Low to High & New Arrivals.

Please suggest me how to change sorting option in my site.

  • For New Arrival you can use New Attribute given by magento admin. Commented Jul 7, 2016 at 11:19
  • Which attribute for New Arrival in Magento 2.?? can you tell me.
    – Nikul
    Commented Jul 7, 2016 at 11:32
  • New Attribute is default available in magento attributes. Commented Jul 7, 2016 at 11:50

4 Answers 4


Step 1: Create plugins in


<?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\Block\Product\ProductList\Toolbar">
        <plugin name="custom_custom_block_toolbar" type="Vendor\Module\Plugin\Catalog\Block\Toolbar" />

    <type name="Magento\Catalog\Model\Config">
        <plugin name="custom_catalog_model_config" type="Vendor\Module\Plugin\Catalog\Model\Config" />


Step 2: Create Config.php in



namespace Vendor\Module\Plugin\Catalog\Model;

class Config
    public function afterGetAttributeUsedForSortByArray(
    \Magento\Catalog\Model\Config $catalogConfig,
    ) {

        $options['low_to_high'] = __('Price - Low To High');
        $options['high_to_low'] = __('Price - High To Low');
        return $options;



Step 3: Create Toolbar.php in


namespace Vendor\Module\Plugin\Catalog\Block;

class Toolbar

    * 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,
    ) {
    $currentOrder = $subject->getCurrentOrder();
    $result = $proceed($collection);

    if ($currentOrder) {
        if ($currentOrder == 'high_to_low') {
            $subject->getCollection()->setOrder('price', 'desc');
        } elseif ($currentOrder == 'low_to_high') {
            $subject->getCollection()->setOrder('price', 'asc');

    return $result;

  • Hardcoding options in template is not good soultion, as well as printing php in javascript. Commented Apr 6, 2017 at 7:18
  • Code has been updated. Please check Commented Oct 24, 2017 at 11:34
  • I request to the the folks who are giving downvote, can you guys specify your reason ? Because it's working fine on my side. Commented Oct 24, 2017 at 18:19

I have asked the same question in the following link: Click here to get some ideas.

Here getOrderUrl() function wont be working in Magento 2. However, It can be controlled by js file path below: vendor/magento/module-catalog/view/frontend/web/js/product/list/toolbar.js


In community edition it needs some coding to achieve that. It can be achieved by preparing some plugins on existing sorting function, inside catalog module. i was adding new sort orders by including whole classes, each representing different order. In case of separating for example, price for two different ones (asc and desc) I included in fact two different orders. Most of your desired sort orders rely on attributes so they shouldn't be hard to implement.

Take a look at: Magento\Catalog\Model\Config - if I remember it well in function getAttributeUsedForSortByArray() all sort by orders are gathered. In plugin on this method I injected additional sort orders as label and sort order's object if I remember it well. In order to add some sorting it is really important to understand it well first, as there is no complete tutorial for magento 2, so rest of coding I leave to you :).


Step 1 : Edit toolbar.phtml inside the folder app/design/frontend/yourpackage/yourtheme/template/catalog/product/list/toolbar.phtml

Step 2 : We will find the default Magento <select> </select> option over there.

Step 3 : We can either comment out that section and create a new one or just add our option in there to make it working too.

<select onchange="setLocation(this.value)">
            <?php /* foreach($this->getAvailableOrders() as $_key=>$_order): ?>
                <option value="<?php echo $this->getOrderUrl($_key, 'asc') ?>"<?php if($this->isOrderCurrent($_key)): ?> selected="selected"<?php endif; ?>>
                    <?php echo $this->__($_order) ?>
            <?php endforeach; */?>  </select>

Step 4 : Then put this code between

<option value="<?php echo $this->getOrderUrl('price', 'asc') ?>"<?php if($this->isOrderCurrent('price') && $this->getCurrentDirection() == 'asc'): ?> selected=”selected”<?php endif; ?>>Price : Low To High</option>
<option value="<?php echo $this->getOrderUrl('price', 'desc') ?>"<?php if($this->isOrderCurrent('price') && $this->getCurrentDirection() == 'desc'): ?> selected=”selected”<?php endif; ?>>Price : High To Low</option>
    <?php endif; // End for removing "Position" sort option ?>
<?php endforeach; ?>

Step 5 : Try to clear your Magento Cache and then refresh your page.

  • 4
    Is this for Magento 2.. Make Sure First..
    – Nikul
    Commented Jul 7, 2016 at 12:20
  • Yes , can you pease where is <select> in Step2, 3 in Magento2?
    – Sushivam
    Commented Sep 10, 2016 at 18:26
  • its for magento 1 Commented Dec 31, 2016 at 10:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.