Skip to content

Instantly share code, notes, and snippets.

@cfxd
Last active June 27, 2023 03:23
Show Gist options
  • Save cfxd/6c95e0d5ea647e7094aca8360dcf1c4f to your computer and use it in GitHub Desktop.
Save cfxd/6c95e0d5ea647e7094aca8360dcf1c4f to your computer and use it in GitHub Desktop.
Create a Custom WooCommerce Product Loop (The Right Way). See https://cfxdesign.com/create-a-custom-woocommerce-product-loop-the-right-way
<?php
if(!function_exists('wc_get_products')) {
return;
}
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1;
$ordering = WC()->query->get_catalog_ordering_args();
$ordering['orderby'] = array_shift(explode(' ', $ordering['orderby']));
$ordering['orderby'] = stristr($ordering['orderby'], 'price') ? 'meta_value_num' : $ordering['orderby'];
$products_per_page = apply_filters('loop_shop_per_page', wc_get_default_products_per_row() * wc_get_default_product_rows_per_page());
$featured_products = wc_get_products(array(
'meta_key' => '_price',
'status' => 'publish',
'limit' => $products_per_page,
'page' => $paged,
'featured' => true,
'paginate' => true,
'return' => 'ids',
'orderby' => $ordering['orderby'],
'order' => $ordering['order'],
));
wc_set_loop_prop('current_page', $paged);
wc_set_loop_prop('is_paginated', wc_string_to_bool(true));
wc_set_loop_prop('page_template', get_page_template_slug());
wc_set_loop_prop('per_page', $products_per_page);
wc_set_loop_prop('total', $featured_products->total);
wc_set_loop_prop('total_pages', $featured_products->max_num_pages);
if($featured_products) {
do_action('woocommerce_before_shop_loop');
woocommerce_product_loop_start();
foreach($featured_products->products as $featured_product) {
$post_object = get_post($featured_product);
setup_postdata($GLOBALS['post'] =& $post_object);
wc_get_template_part('content', 'product');
}
wp_reset_postdata();
woocommerce_product_loop_end();
do_action('woocommerce_after_shop_loop');
} else {
do_action('woocommerce_no_products_found');
}
<?php
if ( have_posts() ) {
do_action( 'woocommerce_before_shop_loop' );
woocommerce_product_loop_start();
if ( wc_get_loop_prop( 'total' ) ) {
while ( have_posts() ) {
the_post();
do_action( 'woocommerce_shop_loop' );
wc_get_template_part( 'content', 'product' );
}
}
woocommerce_product_loop_end();
do_action( 'woocommerce_after_shop_loop' );
} else {
do_action( 'woocommerce_no_products_found' );
}
@andrii-kvlnko
Copy link

Thanks!

@kenzotenma016
Copy link

How are we able to do $featured_products->total when clearly wc_get_products returns an array?

@cfxd
Copy link
Author

cfxd commented May 28, 2020

How are we able to do $featured_products->total when clearly wc_get_products returns an array?

https://github.com/woocommerce/woocommerce/blob/dd49f89e77acaaa097251fe0a5dd69320ded48c6/includes/wc-product-functions.php#L25

@kenzotenma016
Copy link

How are we able to do $featured_products->total when clearly wc_get_products returns an array?

https://github.com/woocommerce/woocommerce/blob/dd49f89e77acaaa097251fe0a5dd69320ded48c6/includes/wc-product-functions.php#L25

ah, yes. I forgot to pass the paginate property.

@jswebschmiede
Copy link

Thx for the snippet.

To avoid the PHP Notice,
array_shift(explode(‘ ‘, $ordering[‘orderby’]));
you can change it to
@reset(explode(' ', $ordering['orderby']));

@honeyamin
Copy link

price filter will not work if use this

@cfxd
Copy link
Author

cfxd commented Apr 27, 2022

@honeyamin ok thanks for letting us all know

@braddalton
Copy link

Use WC_Product_Query if you want everything to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment