Sorting Woocommerce products by category and attributes

I’ve been trying to get this code to work without having to modify the core woocommerce shortcode file, to no avail. It works when entered into
/wp-content/plugins/woocommerce/classes/class-wc-shortcodes.php, but obviously that doesn’t cut it when updates are required.

I’m trying to list out all products based on category as well as an attribute.

The shortcode I’m making is based off of both the list by attribute shortcode, as well as the list by category shortcode:

public static function product_cat_attribute( $atts ) {
$atts = shortcode_atts( array(
    'per_page'  => '12',
    'columns'   => '4',
    'orderby'   => 'title',
    'order'     => 'asc',
    'category'  => '',
    'attribute' => '',
    'filter'    => ''
), $atts, 'product_cat_attribute' );

$query_args = array(
    'post_type'           => 'product',
    'post_status'         => 'publish',
    'ignore_sticky_posts' => 1,
    'posts_per_page'      => $atts['per_page'],
    'orderby'             => $atts['orderby'],
    'order'               => $atts['order'],
    'product_cat'                   => $atts['category'],
    'meta_query'          => WC()->query->get_meta_query(),
    'tax_query'           => array(
        array(
            'taxonomy' => strstr( $atts['attribute'], 'pa_' ) ? 
sanitize_title( $atts['attribute'] ) : 'pa_' . sanitize_title( 
$atts['attribute'] ),
            'terms'    => array_map( 'sanitize_title', explode( ',', 
$atts['filter'] ) ),
            'field'    => 'slug'
        )
    )
);

return self::product_loop( $query_args, $atts, 
'product_cat_attribute');
}

This is also added to the main woocommerce shortcodes array:

public static function init() {
$shortcodes = array(
...
'product_cat_attribute'      => __CLASS__ . '::product_cat_attribute',
...
);

This is what I’ve written to try and have this shortcode function as a separate plugin:

 class WC_custom_shortcode{

  public static function get( $atts ) {
  global $woocommerce;
  return $woocommerce->shortcode_wrapper( array( __CLASS__, 'output' ), 
  $atts );
 }

function product_cat_attribute( $atts ) {
$atts = shortcode_atts( array(
    'per_page'  => '12',
    'columns'   => '4',
    'orderby'   => 'title',
    'order'     => 'asc',
    'category'  => '',
    'attribute' => '',
    'filter'    => ''
), $atts, 'product_cat_attribute' );

$query_args = array(
    'post_type'           => 'product',
    'post_status'         => 'publish',
    'ignore_sticky_posts' => 1,
    'posts_per_page'      => $atts['per_page'],
    'orderby'             => $atts['orderby'],
    'order'               => $atts['order'],
    'product_cat'                   => $atts['category'],
    'meta_query'          => WC()->query->get_meta_query(),
    'tax_query'           => array(
        array(
            'taxonomy' => strstr( $atts['attribute'], 'pa_' ) ? 
sanitize_title( $atts['attribute'] ) : 'pa_' . sanitize_title( 
$atts['attribute'] ),
            'terms'    => array_map( 'sanitize_title', explode( ',', 
$atts['filter'] ) ),
            'field'    => 'slug'
        )
    )
);

return self::product_loop( $query_args, $atts, 
'product_cat_attribute');
}
}
add_shortcode($product_cat_attribute , 'product_cat_attribute');

Unfortunately, nothing occurs when this is in place. Am I on the right track, what should I modify?

Read more here: Sorting Woocommerce products by category and attributes

Leave a Reply

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