Custom Order By Attributes

Custom Order By Attributes

WooCommerce comes up with a few useful product order, which is quite handy as small website, but if you want to increase your user experience and want to reduce bounce rate then you might have to give user few more option for filtering, ordering, etc., so in this tutorial we ‘ll discussing as how easily you can add such options we few lines of code. So tighten your seatbelt. 😉

Directly we cannot short product with attributes/taxonomy in WooCommerce shop page, so what we have to do is first save the attributes in postmeta from there we can sort product by using meta_value. To do this we have to use save_post hook which is called on every post/product create or update.

/**
 * Save product attributes to post metadata when a product is saved.
 *
 * @param int $post_id The post ID.
 * @param post $post The post object.
 * @param bool $update Whether this is an existing post being updated or not.
 *  
 * Refrence: https://codex.wordpress.org/Plugin_API/Action_Reference/save_post
 */
function wh_save_product_custom_meta($post_id, $post, $update) {
    $post_type = get_post_type($post_id);
    // If this isn't a 'product' post, don't update it.
    if ($post_type != 'product')
        return;

    if (!empty($_POST['attribute_names']) && !empty($_POST['attribute_values'])) {
        $attribute_names = $_POST['attribute_names'];
        $attribute_values = $_POST['attribute_values'];
        foreach ($attribute_names as $key => $attribute_name) {
            switch ($attribute_name) {
                //for color (string)
                case 'pa_color':
                    //it may have multiple color (eg. black, brown, maroon, white) but we'll take only the first color.
                    if (!empty($attribute_values[$key][0])) {
                        update_post_meta($post_id, 'pa_color', $attribute_values[$key][0]);
                    }
                    break;
                //for lenght (int)
                case 'pa_length':
                    if (!empty($attribute_values[$key][0])) {
                        update_post_meta($post_id, 'pa_length', $attribute_values[$key][0]);
                    }
                    break;
                default:
                    break;
            }
        }
    }
}

add_action( 'save_post', 'wh_save_product_custom_meta', 10, 3);

Now that we have added attributes to postmeta now we have to build the logic for ordering them

/** 
 *  Main ordering logic for orderby attribute
 *  Refrence: https://docs.woocommerce.com/document/custom-sorting-options-ascdesc/
 */
add_filter('woocommerce_get_catalog_ordering_args', 'wh_catalog_ordering_args');

function wh_catalog_ordering_args($args) {
    global $wp_query;
    if (isset($_GET['orderby'])) {
        switch ($_GET['orderby']) {
            //for attribute/taxonomy=pa_color
            case 'pa-color-asc' :
                $args['order'] = 'ASC';
                $args['meta_key'] = 'pa_color';
                $args['orderby'] = 'meta_value';
                break;
            case 'pa-color-desc' :
                $args['order'] = 'DESC';
                $args['meta_key'] = 'pa_color';
                $args['orderby'] = 'meta_value';
                break;
            //for attribute/taxonomy=pa_length
            case 'pa-length-asc' :
                $args['order'] = 'ASC';
                $args['meta_key'] = 'pa_length';
                $args['orderby'] = 'meta_value_num';
                break;
            case 'pa-length-desc' :
                $args['order'] = 'DESC';
                $args['meta_key'] = 'pa_length';
                $args['orderby'] = 'meta_value_num';
                break;
        }
    }
    return $args;
}

Now we are all set let’s give Site Admin and User the control to chose shorting option.

/**
 *  Lets add the created sorting order to the dropdown list.
 *  Refrence: http://hookr.io/filters/woocommerce_catalog_orderby/
 */
//To under Default Product Sorting in Dashboard > WooCommerce > Settings > Products > Display.
add_filter( 'woocommerce_default_catalog_orderby_options', 'wh_catalog_orderby' );
add_filter('woocommerce_catalog_orderby', 'wh_catalog_orderby');

function wh_catalog_orderby($sortby) {
    $sortby['pa-color-asc'] = 'Sort by Color: A - Z';
    $sortby['pa-color-desc'] = 'Sort by Color: Z - A';
    $sortby['pa-length-asc'] = 'Sort by Length: Small - Large';
    $sortby['pa-length-desc'] = 'Sort by Length: Large - Small';
    return $sortby;
}

Let me know in the comments if you face any probelm while implementing it or you have a better solution to it, then surely we will love to hear form you.

Share this Post:

About Raunak Gupta

I'm an expert Laravel, WooCommerce, WordPress theme and plugin developer, over the time I have developed several sites and applications. I like to help the upcoming developer, So I share my experience through this blog.  

Related Posts:

11 thoughts on “Custom Order By Attributes

  1. emerybouie@gmail.com'

    I’m not fond of adding multiple keys in meta table and ordering the product by that. Isn’t there any better way?

    Reply
  2. ritacesar@hotmail.com'

    Hi Raunak, in my case not execute. Not show the attributes, I don’t know what happens.
    My WordPress version is 4.7.3

    Can you help me?

    Reply
  3. pfannerlol@gmail.com'

    Hey Raunak, the add_action for wh_save_product_custom_meta is missing in the first code part.

    Reply
  4. fuzztoneage@gmail.com'

    Hi I have searched for a code like this for several days. In my case, the attributes are for beers and I need to filter by attribute value, alcohol level, bitterness and color. try to adapt your code, it does not give errors but I can not make it work. I apologize for my bad English but use a translator since I speak Spanish. Regards

    Reply
    • Hi Miguel,

      I missed out to add save_post action. Now I have updated my post, so it should be working now.
      And just for you, I have translated the above line in Spanish 😉

      “Me perdí para agregar la acción save_post. Ahora actualicé mi publicación, por lo que debería estar funcionando ahora.”

      Reply
  5. JohannaGain@yahoo.com'

    I like this article, useful stuff on here : D.

    Reply
  6. ayanastudios@gmail.com'

    tried this code but sorting is not being done, have created an attribute named colour and changed in all the codes given above from color to colour. But sorting of asc to desc or vice-versa not happening, it displays a blank page.

    Reply
    • Hi Malar,

      Can you please share you code that you have written, and have you added add_action( 'save_post', 'wh_save_product_custom_meta', 10, 3); ?

      Reply

Leave a Comment

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


*