Well woocommerce_products_will_display()
is pluggable, meaning you can define it in your own functions.php (or site-specific plugin) and alter it, having it return true
for your specific template/page.
I think it could stand for some tweaking and a filter.
EDIT
I played around with this a bit more. Typically changing the posts that you want to retrieve is done in the pre_get_posts
hook. I took a look at what WooCommerce is doing. They are adding something to the pre_get_posts
hook and calling their special query stuff from there.
But their special query stuff dies if you aren't on a WooCommerce page. So, it made me thing that maybe we could just call it ourselves from our own function. I put this together and coupled with a special page template for a page called "on-sale" (basically just a copy of the shop template), seems to show just the for sale items with proper sorting and pagination.
Your mileage may vary, but I hope it helps.
function kia_pre_get_posts( $q ){
// We only want to affect the main query
if ( ! $q->is_main_query() ) {
return;
}
// Fix for verbose page rules
if ( is_page('on-sale') ) {
$q->set( 'post_type', 'product' );
$q->set( 'page_id', '' );
$q->set( 'page', '' );
$q->set( 'pagename', '' );
$meta_query = array( array(
'key' => '_sale_price',
'value' => 0,
'compare' => '>'
) );
$q->set( 'meta_query', $meta_query );
if ( isset( $q->query['paged'] ) ) {
$q->set( 'paged', $q->query['paged'] );
}
// Fix conditional Functions
$q->is_archive = true;
$q->is_post_type_archive = true;
$q->is_singular = false;
$q->is_page = false;
}
$wc_query = WC()->query;
$wc_query->product_query( $q );
if ( is_search() ) {
add_filter( 'posts_where', array( $wc_query, 'search_post_excerpt' ) );
add_filter( 'wp', array( $wc_query, 'remove_posts_where' ) );
}
add_filter( 'posts_where', array( $wc_query, 'exclude_protected_products' ) );
// We're on a shop page so queue the woocommerce_get_products_in_view function
add_action( 'wp', array( $wc_query, 'get_products_in_view' ), 2);
// And remove the pre_get_posts hook
$wc_query->remove_product_query();
}
add_action( 'pre_get_posts', 'kia_pre_get_posts' );