How to add custom product sorting options in WooCommerce

By default, WooCommerce comes with 6 sorting options:

  • Sort by popularity
  • Sort by average rating
  • Sort by newness
  • Sort by price: low to high
  • Sort by price: high to low

In this example, I’ll add an extra option to sort by sale status.

Adding a new sorting option

woocommerce_catalog_orderby hook gives you control over the default sorting options to display. In order to add a new option, you need to add it to the current options array.

Code:

Now add the following code to order by the _sale_price custom field.

Code:

Advanced sorting

However, if your sorting needs are more advanced, then you can hook into pre_get_posts instead of woocommerce_get_catalog_ordering_args.

The pre_get_posts hook gives developers access to the $query object and possibility to modify the query. It’s really powerful and useful for altering the main loop and creating custom queries. See the docs here.

In this example, we’ll show products from a given category ‘Cars’ and sort them by sale status.

Code:

4 thoughts on “How to add custom product sorting options in WooCommerce”

  1. Great post. Currently, I am having a similar problem in which I guess you can help me!

    I have a meta key value pair like this: key: ‘woodate’, value: ’01 Sep, 2017′) for products which belong to event category.

    So I want to sort these event category products(on category archive page) in ASC order by the ‘woodate’ key.

    Can you please suggest how to do that? I have many ways but it’s not working.

    1. Hi Ranjan,

      Try this code: https://pastebin.com/heHyWjA7 Change Line #19 ‘terms’ to your product event category slug. Also, change #line 27 $query->set( ‘order’, ‘DESC’ ) to ASC. ‘meta_value_num’ – Allows you to order by numeric meta value, but ‘woodate’ is string so you need to convert it to integer (timestamp) first or create a new meta key e.g. woodate_timestamp with timestamp value. You can use strtotime() function.

  2. Hi. I’ve tried several different code snippets from various places on the web but none have worked for me. I’m using Toolset to create a set of custom fields and have a Size field with the slug pm-machine-size-a. I’d like to sort by Size; the sort option appears in the dropdown but selecting it has no product found. Every item in the inventory has that custom field populated. Can you coach me on where I’m making a mistake, please?


    //add Size to catalog sort
    function theme_catalog_orderby( $catalog_orderby_options ) {
    $catalog_orderby_options['size'] = __( 'Sort by Size', 'woocommerce' );

    return $catalog_orderby_options;
    }

    add_filter( 'woocommerce_catalog_orderby', 'theme_catalog_orderby' );

    /**
    * Returns an array of arguments for ordering products based on the selected values.
    *
    * @uses woocommerce_get_catalog_ordering_args hook
    * @return array
    */
    function theme_get_catalog_ordering_args( $args ) {

    $orderby_value = isset( $_GET['orderby'] ) ? woocommerce_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
    if ( 'size' == $orderby_value ) {

    $args['meta_key'] = 'pm-machine-size-a';
    $args['orderby'] = 'meta_value_num';
    $args['order'] = 'DESC';

    }

    return $args;
    }

    add_filter( 'woocommerce_get_catalog_ordering_args', 'theme_get_catalog_ordering_args' );

    1. Hi Michael,

      Sorry I’m on a short vacation. I’ll be able to help you on Monday. But, this $args[‘orderby’] = ‘meta_value_num’; means that your meta key should be a numerical value so if you have a string value, then it won’t work. This $args[‘orderby’] might be a problem.

Leave a Reply

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