WooCommerce Shortcode to list Categories and Featured Products

WooCommerce comes with the ability to set featured products along with the option to display them as a list using a WordPress shortcode. This article will show you how to add a new shortcode to WooCommerce to display a list of categories and the featured products within these categories. For this shortcode we want to allow the user to be able to set the categories to use and the order for which to appear, also how many featured items to be displayed within each category.

A wordpress shortcode can be added by registering the shortcode function with wordpress using add_shortcode, the following code registers our shortcode with the necessary arguments.

<?php
add_shortcode( 'featured_product_categories', 'jc_featured_products' );
function jc_featured_products($atts){
	global $woocommerce_loop;
 
	extract(shortcode_atts(array(
		'cats' => '',	// list of categories in the format 0,1,2,3,4
		'tax' => 'product_cat',	// taxonomy use
		'per_cat' => '3',	// max featured items to display per category
		'columns' => '3',	// columns size
	), $atts));
 
	// get list of categories if no categories have been chosen
	if(empty($cats)){
		$terms = get_terms( 'product_cat', array('hide_empty' => true, 'fields' => 'ids'));
		$cats = implode(',', $terms);
	}
 
	// explode csv of categories into array e.g. array(0,1,2,3,4)
	$cats = explode(',', $cats);
 
	ob_start();
 
	// output list of featured products within categories
 
	return '<div class="woocommerce jc_featured_products">' . ob_get_clean() . '</div>';
}
?>

Now that our shortcode has been registered with wordpress, it will replace any occurrence of:

[featured_product_categories cats="" tax="" per_cat="" columns="" /]

We need to loop through all the categories passed as an argument, then query the woocommerce catalogue and retrieve the featured products for that category. To do this we make use of wordpress WP_Query class and the tax_query and meta_query arguments to query the specific categories and visible and featured products.

<?php
foreach($cats as $cat){
	// get the product category
	$term = get_term( $cat, $tax);
 
	// setup product query
	$args = array(
		'post_type'	=> 'product',
		'post_status' => 'publish',
		'ignore_sticky_posts'	=> 1,
		'posts_per_page' => $per_cat,
		'tax_query' => array(
			// get products in the specified taxonomies
			array(
				'taxonomy' => $tax,
				'field' => 'id',
				'terms' => $cat,
			)
		),
		'meta_query' => array(
			// get products that are allowed to be displayed in the catalogue
			array(
				'key' => '_visibility',
				'value' => array('catalog', 'visible'),
				'compare' => 'IN'
			),
			// get only products marked as featured
			array(
				'key' => '_featured',
				'value' => 'yes'
			)
		)
	);
 
	// set woocommerce columns
	$woocommerce_loop['columns'] = $columns;
 
	// query database
	$products = new WP_Query( $args );
}
?>

Lets now put this all together and display the products using the same format as WooCommerce does, by including the content-product template.

<?php
add_shortcode( 'featured_product_categories', 'jc_featured_products' );
function jc_featured_products($atts){
 
	global $woocommerce_loop;
 
	extract(shortcode_atts(array(
		'cats' => '',	// list of categories in the format 0,1,2,3,4
		'tax' => 'product_cat',	// taxonomy use
		'per_cat' => '3',	// max featured items to display per category
		'columns' => '3',	// columns size
	), $atts));
 
	// get list of categories if no categories have been chosen
	if(empty($cats)){
		$terms = get_terms( 'product_cat', array('hide_empty' => true, 'fields' => 'ids'));
		$cats = implode(',', $terms);
	}
 
	// explode csv of categories into array e.g. array(0,1,2,3,4)
	$cats = explode(',', $cats);
 
	// escape early if no categories
	if(empty($cats)){
		return '';
	}
 
	ob_start();
 
	foreach($cats as $cat){
 
		// get the product category
		$term = get_term( $cat, $tax);
 
		// setup query
		$args = array(
			'post_type'	=> 'product',
			'post_status' => 'publish',
			'ignore_sticky_posts'	=> 1,
			'posts_per_page' => $per_cat,
			'tax_query' => array(
				// get products in the specified taxonomies
				array(
					'taxonomy' => $tax,
					'field' => 'id',
					'terms' => $cat,
				)
			),
			'meta_query' => array(
				// get products that are allowed to be displayed in the catalogue
				array(
					'key' => '_visibility',
					'value' => array('catalog', 'visible'),
					'compare' => 'IN'
				),
				// get only products marked as featured
				array(
					'key' => '_featured',
					'value' => 'yes'
				)
			)
		);
 
		// set woocommerce columns
		$woocommerce_loop['columns'] = $columns;
 
		// query database
		$products = new WP_Query( $args );
 
		$woocommerce_loop['columns'] = $columns;
 
		if ( $products->have_posts() ) : ?>
 
			<h2><a href="<?php echo get_term_link($term, $tax ); ?>"><?php echo $term->name; ?></a></h2>
			<?php woocommerce_product_loop_start(); ?>
 
				<?php while ( $products->have_posts() ) : $products->the_post(); ?>
 
					<?php woocommerce_get_template_part( 'content', 'product' ); ?>
 
				<?php endwhile; // end of the loop. ?>
 
			<?php woocommerce_product_loop_end(); ?>
 
		<?php endif;
 
		wp_reset_postdata();
	}
 
	return '<div class="woocommerce">' . ob_get_clean() . '</div>';
}
?>


Liked this article? help spread the word.