14

I couldn't find the right way to get the list of all products for a given category ID (not category name).

The code I am using to get the categories list is the following, it works fine:

$args = array(
           'orderby'    => $orderby,
           'order'      => $order,
           'hide_empty' => 0,
           'include'    => $ids,
           'parent'    => 0,
     ); 

$categories = get_terms( 'product_cat', $args );

However, now for a given category ID (say 47), I couldn't find the way to get its relevant products. I tried the following way:

$args = array( 
    'posts_per_page' => 5,
    'offset'=> 1,
    'category' => 47
 );

$products = get_posts( $args );
echo var_dump($products);

Debugging the $products array returns always 0 which is wrong since I know there is some products under the category with ID 47. Any ideas how to fix my code?

  • 1
    category or product_category? – fuxia May 14 '14 at 18:34
18

I suspect the main problem is that you should be using the WP_Query object rather than get_posts(). The later by default only returns items with a post_type of post not products,

So given a category with ID 26, the following code would return it's products (WooCommerce 3+):

    $args = array(
    'post_type'             => 'product',
    'post_status'           => 'publish',
    'ignore_sticky_posts'   => 1,
    'posts_per_page'        => '12',
    'tax_query'             => array(
        array(
            'taxonomy'      => 'product_cat',
            'field' => 'term_id', //This is optional, as it defaults to 'term_id'
            'terms'         => 26,
            'operator'      => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
        ),
        array(
            'taxonomy'      => 'product_visibility',
            'field'         => 'slug',
            'terms'         => 'exclude-from-catalog', // Possibly 'exclude-from-search' too
            'operator'      => 'NOT IN'
        )
    )
);
$products = new WP_Query($args);
var_dump($products);

In earlier versions of WooCommerce the visibility was stored as a meta field, so the code would be:

    $args = array(
    'post_type'             => 'product',
    'post_status'           => 'publish',
    'ignore_sticky_posts'   => 1,
    'posts_per_page'        => '12',
    'meta_query'            => array(
        array(
            'key'           => '_visibility',
            'value'         => array('catalog', 'visible'),
            'compare'       => 'IN'
        )
    ),
    'tax_query'             => array(
        array(
            'taxonomy'      => 'product_cat',
            'field' => 'term_id', //This is optional, as it defaults to 'term_id'
            'terms'         => 26,
            'operator'      => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
        )
    )
);
$products = new WP_Query($args);
var_dump($products);

Here we are only returning visible products, 12 per page.

Have a look through http://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters for more details about how the category targeting works - it's often more useful to retrieve it by slug than by ID!

  • Solution worked. Nice explanation. – Kamesh Jungi Jul 10 '15 at 6:26
  • 1
    As of Woocommerce 3, visibility is changed to taxonomy instead of meta so you need to change the meta_query to tax_query. See wordpress.stackexchange.com/a/262628/37355. – jarnoan Oct 18 '17 at 7:10
  • Your conclusion about get_posts() is wrong. You can replace new WP_Query($args) with get_posts($args) in your code and it will work. – Bjorn Jul 14 '18 at 9:43
2

change category (category-slug-name) by id or name or slug

<?php

$args = array( 'post_type' => 'product', 'stock' => 1, 'posts_per_page' => 2,'product_cat' => 'category-slug-name', 'orderby' =>'date','order' => 'ASC' );
  $loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
global $product; 
?>
Within loop we can fetch Product image, title, description, price etc. 

<?phpendwhile;wp_reset_query(); ?>
2

A bit late, but would like to clarify things and provide a cleaner answer. User @benz001 gave a possible valid answer, but said something wrong: get_posts returns any kind of post-types, defaulting to posts post-type, just like WP_Query. The real differences between the two are wonderfully explained HERE.

The fact is, the OP was simply missing some parameters into the $args array:

  • The definition of the post-type he is searching for:

        'post_type'             => 'product',
    
  • And the modification of the "taxonomy part" of the search query:

        'tax_query' => array(
            array(
                'taxonomy' => 'product_cat',
                'terms' => 26,
                'operator' => 'IN',
            )
        )
    

This way your next lines

$products = new WP_Query($args);
var_dump($products);

Will show you the needed products :)

All other additional parameters shown by @benz001 are of course valid but not requested by the OP, so I decided to leave them behind in this answer.

1
$products = wc_get_products(array(
    'category' => array('your-category-slug'),
));
  • OP specifically asked for getting products using a category ID, however, this helped me, so I'll upvote anyhow. Just be aware it doesn't answer the original question – dKen Sep 24 at 17:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.