19

I would like to display 6 featured products from my woocommerce store on my home-page.php template. After some researched I found that the right way to do this was through a custom loop,( I do not wish to use shortcodes because I would like to add additional classes for styling etc. ) I also found that the key that woocommerce uses for the featured products is '_featured'. I put together the code below to display any products that I chose to be featured products in my store, but it doesn't work... Any help is appreciated.

<?php

    $args = array(
        'post_type'   => 'product',
        'stock'       => 1,
        'showposts'   => 6,
        'orderby'     => 'date',
        'order'       => 'DESC' ,
        'meta_query'  => array(
            array(
                'key'     => '_featured',
                'value'   => 0,
                'compare' => '>',
                'type'    => 'numeric'
            )
        )
    );

    $loop = new WP_Query( $args );
    while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?>

        <li>    
            <?php 
                if ( has_post_thumbnail( $loop->post->ID ) ) 
                    echo get_the_post_thumbnail( $loop->post->ID, 'shop_catalog' ); 
                else 
                    echo '<img src="' . woocommerce_placeholder_img_src() . '" alt="Placeholder" width="65px" height="115px" />'; 
            ?>
            <h3><?php the_title(); ?></h3>

            <?php 
                echo $product->get_price_html(); 
                woocommerce_template_loop_add_to_cart( $loop->post, $product );
            ?>    
        </li>

<?php 
    endwhile;
    wp_reset_query(); 
?>
  • Add the result from var_dump( get_meta_values( '_featured', 'product' ); where the function get_meta_values is supported by the custom function explained in this answer – Pieter Goosen Jul 24 '15 at 4:34
17

Change your args to be like this:

$meta_query   = WC()->query->get_meta_query();
$meta_query[] = array(
    'key'   => '_featured',
    'value' => 'yes'
);
$args = array(
    'post_type'   =>  'product',
    'stock'       =>  1,
    'showposts'   =>  6,
    'orderby'     =>  'date',
    'order'       =>  'DESC',
    'meta_query'  =>  $meta_query
);

If you go to wp-content/plugins/woocommerce/includes/class-wc-shortcodes.php (@595) you can find how it's done for WC shortcodes.

  • 3
    They key to note is that '_featured' is not stored as a numeric value. It is stored as a string 'yes' or 'no'. Everything else in the OP question should work, worked for me. – i_a Jul 3 '16 at 17:02
  • 1
    As of WooCommerce 3.0, this solution no longer works. Please see my updated answer below. – dpruth Jun 12 '18 at 19:02
22

This has changed in WooCommerce 3.0. It's not simply a meta_query, but now includes a tax_query. The arguments are now:

    $meta_query  = WC()->query->get_meta_query();
    $tax_query   = WC()->query->get_tax_query();
    $tax_query[] = array(
        'taxonomy' => 'product_visibility',
        'field'    => 'name',
        'terms'    => 'featured',
        'operator' => 'IN',
    );

    $args = array(
        'post_type'           => 'product',
        'post_status'         => 'publish',
        'ignore_sticky_posts' => 1,
        'posts_per_page'      => $atts['per_page'],
        'orderby'             => $atts['orderby'],
        'order'               => $atts['order'],
        'meta_query'          => $meta_query,
        'tax_query'           => $tax_query,
    );

See woocommerce/includes/class-wc-shortcodes.php

  • 1
    Just what I was looking for! – joshkrz May 10 '18 at 22:09
  • Also for Woocommerce 3.0, they recommend using wc_placeholder_img_src instead of woocommerce_placeholder_img_src. – Robotnicka May 25 '18 at 0:46
6

Featured Products Loop in WooCommerce 3

<ul class="products">
<?php
$args = array(
    'post_type' => 'product',
    'posts_per_page' => 12,
    'tax_query' => array(
            array(
                'taxonomy' => 'product_visibility',
                'field'    => 'name',
                'terms'    => 'featured',
            ),
        ),
    );
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
    while ( $loop->have_posts() ) : $loop->the_post();
        wc_get_template_part( 'content', 'product' );
    endwhile;
} else {
    echo __( 'No products found' );
}
wp_reset_postdata();
?>
4

According to the WooCommerce Wiki:

Building custom WP_Queries or database queries [to retrieve products] is likely to break your code in future versions of WooCommerce as data moves towards custom tables for better performance.

WooCommerce advocates using wc_get_products() or WC_Product_Query() instead of WP_Query() or get_posts().

I've written a post with the code I used to achieve what you want here: https://cfxdesign.com/create-a-custom-woocommerce-product-loop-the-right-way/

  • sorry, without seeing some written code, it is hard to understand your article. Can you please include some coding ? – HOY Jun 5 at 14:59
  • @HOY the embed plugin was broken; it's fixed now and you can see the code! – cfx Jun 5 at 20:07
  • thank you, while looking for solutions, I came up with this one below. I am not sure how it differs from yours since I was not able to check yours throughly but it is very short and helped me with a custom product loop. kathyisawesome.com/woocommerce-modifying-product-query – HOY Jun 5 at 20:28
1

I know this is quite old, but I've just shared an alternative solution here and I think it can help those reaching this topic too.

Instead of using meta_query or tax_query, you can use wc_get_featured_product_ids() too:

$args = array(
    'post_type'           => 'product',
    'posts_per_page'      => 6,
    'orderby'             => 'date',
    'order'               => 'DESC',
    'post__in'            => wc_get_featured_product_ids(),
);

$query = new WP_Query( $args );

I hope it helps!

1

Based on: https://github.com/woocommerce/woocommerce/wiki/wc_get_products-and-WC_Product_Query

I would try:

outside loop:

$args = array (
'limit' => 6,
'orderby' => 'title',
'order' => 'ASC',
'category' => $club_cat,
'stock_status' => 'instock',
'featured' => true,

 );

 $products = wc_get_products( $args );

in the loop:

$query = new WC_Product_Query( array(
'limit' => 6,
'orderby' => 'title',
'order' => 'ASC',
'category' => $club_cat,
'stock_status' => 'instock',
'featured' => true,
'return' => 'ids',

 ) );

 $products = $query->get_products();
0

if you take a look in the database in wp_postmeta table you will see meta_key will be _featured and meta_value will be yes or no so instead of value 0 or 1 write yes or no

<?php
    $q = new WP_Query([
      'post_type'   =>  'product',
      'stock'       =>  1,
      'showposts'   =>  3,
      'orderby'     =>  'date',
      'order'       =>  'DESC',
      'meta_query'  =>  [ 
        ['key' => '_featured', 'value' => 'yes' ]
        ]
    ]);
    if ( $q->have_posts() ) :
        while ( $q->have_posts() ) : $q->the_post();
            // display product info
        endwhile; wp_reset_query();
    endif;
?>
0
<ul class="products">
    <?php
        $args = array(
            'post_type' => 'product',
            'posts_per_page' => 12,
            'tax_query' => array(
                    array(
                        'taxonomy' => 'product_visibility',
                        'field'    => 'name',
                        'terms'    => 'featured',
                    ),
                ),
            );
        $loop = new WP_Query( $args );
        if ( $loop->have_posts() ) {
            while ( $loop->have_posts() ) : $loop->the_post();
               echo '<p>'.get_the_title().'</p>';
            endwhile;
        } else {
            echo __( 'No products found' );
        }
        wp_reset_postdata();
    ?>
</ul><!--/.products-->
  • Please edit your answer, and add an explanation: why could that solve the problem? – fuxia Apr 3 at 14:40

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.