WooCommerce: Display ONLY on-sale products in Shop

archive, filter, woocommerce, wordpress

Solution

@mirus' answer regarding the shortcode gave me the idea to check out how WooCommerce is querying only the on-sale items. Apparently WooCommerce has a `wc_get_product_ids_on_sale()` function that will return the IDs of the on-sale items. Then we can easily adjust the query using the `post__in` parameter to only return those specific items.

WooCommerce has a `woocommerce_product_query` hook in the `class-wc-query.php` class that allows for us to modify the query before it is run.... it is run on `pre_get_posts` which is the usual place for modifying the query. Using Woo's hook just means you let them handle the majority of the conditional logic about when this query modification should be applied.

add_action( 'woocommerce_product_query', 'so_20990199_product_query' );

function so_20990199_product_query( $q ){

    $product_ids_on_sale = wc_get_product_ids_on_sale();

    $q->set( 'post__in', $product_ids_on_sale );

}

Problem

I need to create a products archive page (usually the Shop page in WooCommerce) but displays ONLY the ON SALE products. Basically it should use the same template layout as that in the `archive-product.php`. There will be a link in the main menu that will direct to this page. How do I go about this? UPDATE I managed to filter out the ON SALE products with the code below placed just above the `if ( have_posts() ) :` line... ``` $args = array( 'post_type' => 'product', 'order' => 'ASC', 'paged' => $paged, 'meta_query' => array( array( 'key' => '_sale_price', 'value' => 0, 'compare' => '>', 'type' => 'numeric' ) ) ); query_posts( $args ); ``` The code is placed in a copy of `archive-product.php` which I named `archive-product_sale.php` and made as a page template. However, this only works for Simple products type and I need it to work for both Simple products and Variable products type.

Original source