Using WP_Query to pull and display WooCommerce Products

In a perfect world, sourcing quality products and providing great service would be all that was needed to get sales, but in the modern, competitive online world presentation is just as important for several reasons. For one, users are pressed for time and need to be able to see at a glance the kind of products you have for sale. Secondly, the freedom offered by the internet means that there’s a lot of shifty websites looking to scam people with fake products and non-existent customer service; a professional site layout and design (along with clear company details and contact information) provides users with reassurance that you are a serious seller.

wpquery

An Introduction to the WP_Query WordPress Class

Thankfully, the power of WordPress and WooCommerce provides a solid base for crafting an effective sales platform, and with clever use of WP_Query, you can create dynamic, original product displays with a range of sorting methods to get all your wares in easy reach of your customers. What is WP_Query? It’s one of the core classes included with WordPress that can be used to create complex queries (a bit like searches, but with a lot more specifics!) that will return posts, which can then be displayed in a loop where we will get access to some of the important functions therein such as the_title() or the_excerpt(); the core building blocks we can use for manipulating our display.

Note: Something very important to be aware of when working with WP_Query is that using it has an impact on the variables that might need to be queried again later, so it’s necessary to reset global variables to their original state with the wp_reset_postdata() function; you’ll see this applied in our example code later in this article.

In this article though, we’ll go a step further by using WP_Query to grab not standard WordPress posts, but WooCommerce products; we’ll also look at sorting the queries to ensure that you’re getting the products that matter most for your display, whether its available products, items on promotion etc…

In the following sections we’ll be providing multiple code examples that you can freely use on your site; you should pack the example code into a shortcode which will display the posts generated by WP_Query, or alternatively you can create a widget with the example code in that you can place in any of the available position of your theme as needed. Ready to get coding?Then let’s go!

The base code structure

At the very beginning, the first thing we’re going to need is a starting block of code that we can modify to suit our needs:

<?php
$params = array('posts_per_page' => 5); // (1)
$wc_query = new WP_Query($params); // (2)
?>
<?php if ($wc_query->have_posts()) : // (3) ?>
<?php while ($wc_query->have_posts()) : // (4)
                $wc_query->the_post(); // (4.1) ?>
<?php the_title(); // (4.2) ?>
<?php endwhile; ?>
<?php wp_reset_postdata(); // (5) ?>
<?php else:  ?>
<p>
     <?php _e( 'No Products' ); // (6) ?>
</p>
<?php endif; ?>

The above code pulls the titles of the five most-recent posts from our WordPress database using the following process:

  1. An array of parameters for WP_Query to work with is created; to start with it’s just the basic posts, but by adding more specifics to these parameters we can achieve different results for our queries.
  2. WP_Query is used to query the parameters created in the first line.
  3. The query is checked to see if it returned any results.
  4. If there are results, then we iterate over them:
    1. First, setting the global variable $post, which ensures that the next function works.
    2. Second, setting the the_title() variable, which is responsible for displaying the post title.
  5. Then, when the posts are displayed, we return the $post variable to its original state with the wp_reset_postdata function.
  6. In the event that the check in step 3 finds that there are no posts to display, instead of iterating over non-existent results we just display an appropriate prompt.

Pulling WooCommerce Products instead of WordPress Posts

Ok, so this base code takes care of the hard part; pulling the recent posts. But there’s quite an obvious issue for our needs, since we’re looking to display our latest WooCommerce products, not posts. The reason that posts are displayed by default is due to the post_type parameter; if left unset in the code then it will remain at its default setting, which is to look for posts. So all we need to do is change the query parameters array to include the post_type parameter and tell it to grab products, not posts:

$params = array(
        'posts_per_page' => 5, 
        'post_type' => 'product'
);

As you can see, all we’ve done is added a post_type variable to the array, and set it’s value to “product”; the query will now look for WooCommerce products instead of posts.

That was good for a little warm-up, but let’s get a bit more sophisticated!

Displaying on-promotion WooCommerce products

What’s one of the best ways to get sales fast? Run a promotion! If you’ve got products on sale, then you’ll want them to get center-stage in any product display. Doing so is pretty easy; we’re just going to modify our parameters accordingly. In WooCommerce, a sale_price field is responsible for defining the special discounted price; when the product is no longer discounted this field is empty. We can use this behavior to our advantage by adding a check that sees if the sale_price field has a value greater than or equal to zero to our parameters, like so:

$params = array(
'posts_per_page' => 5, 
'post_type' => 'product',
'meta_key' => '_sale_price',
'meta_value' => '0',
'meta_compare' => '>='
);

Displaying variant promotional products

The last section’s code takes care of displaying products that are on promotion, but what about variants of a single product? After all, if one variant is on sale we’re quite likely to want the rest of the variants on sale too! The reason the last section’s code doesn’t display the variants as standard is because WooCommerce stores each product variant as a separate post, and as a post of another type. To get around this, we’ll need to make another small modification to our parameters array:

$params = array(
'posts_per_page' => 5, 
'post_type' => array('product', 'product_variation'),
'meta_key' => '_sale_price',
'meta_value' => 0,
'meta_compare' => '>='
'meta_type' => 'NUMERIC'
);

In the above code we take advantage of the fact that the post_type parameter may take as a value an array of different types of post that should be considered when querying the database.

Displaying products of a given price range

Let’s try something a bit more complex; displaying a range of products that fall within a particular price range. Each product’s price is stored in the _price field. However, if you recall from the above sections, the sales price is stored separately in the sales_price field. Thus, when querying we’ll have to consider both of these values to ensure accuracy. We’ll start with an easier variant where we retrieve any product cheaper than 5:

$params = array(
        'posts_per_page' => 100, 
        'post_type' => array('product', 'product_variation'),
        'meta_query' => array(
            'relation' => 'OR',
            array(
                'key' => '_price',
                'value' => 5,
                'compare' => '<=',
                'type' => 'NUMERIC'
            ),
            array(
                'key' => '_sales_price',
                'value' => 5,
                'compare' => '<=',
                'type' => 'NUMERIC'
            )
        )
);

In this code we’ve used the meta_query parameter, which allows us to build more complex queries using posts’ fields as a variable. However, by default this parameter will connect each condition with an AND conjunction. What this means is that the default setting will require all conditions to be true before a product is displayed, when we only need one of the conditions to be true. To get around this, we added a relation parameter to the met_query parameter, defining the connecting conjunction as OR rather than AND; now only one of the conditions needs to be true for the product to be displayed.

Now we come to the main part of this example where we define the price range for both the standard and on-sale products:

$params = array(
        'posts_per_page' => 5, 
        'post_type' => array('product', 'product_variation'),
        'meta_query' => array(
            'relation' => 'OR',
            array(
                array(
                    'key' => '_price',
                    'value' => 10,
                    'compare' => '>=',
                    'type' => 'NUMERIC'
                ),
                array(
                    'key' => '_price',
                    'value' => 15,
                    'compare' => '<=',
                    'type' => 'NUMERIC'
                )
            ),
            array(
                array(
                    'key' => '_sale_price',
                    'value' => 10,
                    'compare' => '>=',
                    'type' => 'NUMERIC'
                ),
                array(
                    'key' => '_sale_price',
                    'value' => 15,
                    'compare' => '<=',
                    'type' => 'NUMERIC'
                )
            )
        )
);

Displaying available products only

Your customers won’t be very pleased if you try to sell them a product on your frontpage that you don’t have in stock, so it’s a good idea to include such a check in your code. The storage situation is handled by the _stock_status field, which takes two values: instock and outofstock. So, to show the products that are set at a lower price than 5 and are in stock, we’ll need to use the following parameters:

$params = array(
        'posts_per_page' => 5, 
        'post_type' => array('product', 'product_variation'),
        'meta_query' => array(
            array(
                'key' => '_price',
                'value' => 5,
                'compare' => '<',
                'type' => 'NUMERIC'
            ),
            array(
                'key' => '_stock_status',
                'value' => 'instock'
            )
        )
);

Displaying products with a defined stock level

In the last section we ensured that the query would only select products that were in-stock; but what if we wanted to specifically display products we have a large stock of to make sure we can meet demand? WooCommerce doesn’t just include fields for a binary in-stock/not in-stock situation; there’s also another field, _stock, which stores the total available stock of a given item. Using this, we can set our code to display only products that have a certain amount of stock; for example, products that have more than 5 available:

$params = array(
        'posts_per_page' => 100, 
        'post_type' => array('product', 'product_variation'),
        'meta_query' => array(
            array(
                'key' => '_stock',
                'value' => 5,
                'compare' => '>',
                'type' => 'NUMERIC'
            )
        )
);

Displaying selected product variants

And to finish off this article, here’s something very simple but still noteworthy; a method for displaying a particular product’s variants:

$params = array(
        'posts_per_page' => 5, 
        'post_type' => array('product_variation'),
        'post_parent' => 15
);

In this code we use the fact that product variants, as well as a post type variable, also set a field to the ID value of the parent-product. So in the above example we display up to 5 product variants that have an ID equal to 15; a great function if you’ve got a lot of interesting variants to sell! Of course, as with all types of posts, we may add multiple parent-product IDs as an array to the parameter:

$params = array(
        'posts_per_page' => 5, 
        'post_type' => array('product_variation'),
        'post_parent' => array(15, 25)
);

Summary

As we’ve explored in this post, WP_Query offers many interesting opportunities when if comes to displaying WooCommerce products. Each product several fields that can be used to differentiate between items so that you can search for specific criteria, creating a tailored layout that offers near unlimited possibilities for filtering and matching products.

We hope this post helps you get started with using WP_Query with WooCommerce, and if you’ve got any tips of your own why not add them in the comments below; we’re always interested in hearing how our users take advantage of WordPress’ functionalities!

Using WP_Query to pull and display WooCommerce Products 4.225 (84.49%) 98 votes
Share
This article was first published July 27th, 2015