Instantly share code, notes, and snippets.

What would you like to do?
Done the 2 fixes for the code to work and added warning on how to insert code
This code shows pagination for WooCommerce shortcodes when it's embeded on single pages.
Include into functions.php. DO NOT include the first line <?php twice in function.php (line 33) otherwise this will break the code
if ( ! is_admin() ) {
// ---------------------- FRONTPAGE -------------------
if ( defined('WC_VERSION') ) {
// ---------------------- WooCommerce active -------------------
* Set Pagination for shortcodes custom loop on single-pages.
* @uses $woocommerce_loop;
add_action( 'pre_get_posts', 'kli_wc_pre_get_posts_query' );
function kli_wc_pre_get_posts_query( $query ) {
global $woocommerce_loop;
// Get paged from main query only
// ! frontpage missing the post_type
if ( is_main_query() && ( $query->query['post_type'] == 'product' ) || ! isset( $query->query['post_type'] ) ){
if ( isset($query->query['paged']) ){
$woocommerce_loop['paged'] = $query->query['paged'];
if ( ! $query->is_post_type_archive || $query->query['post_type'] !== 'product' ){
$query->is_paged = true;
$query->query['paged'] = $woocommerce_loop['paged'];
$query->query_vars['paged'] = $woocommerce_loop['paged'];
/** Prepare Pagination data for shortcodes on pages
* @uses $woocommerce_loop;
add_action( 'loop_end', 'kli_query_loop_end' );
function kli_query_loop_end( $query ) {
if ( ! $query->is_post_type_archive || $query->query['post_type'] !== 'product' ){
// Cache data for pagination
global $woocommerce_loop;
$woocommerce_loop['pagination']['paged'] = $woocommerce_loop['paged'];
$woocommerce_loop['pagination']['found_posts'] = $query->found_posts;
$woocommerce_loop['pagination']['max_num_pages'] = $query->max_num_pages;
$woocommerce_loop['pagination']['post_count'] = $query->post_count;
$woocommerce_loop['pagination']['current_post'] = $query->current_post;
* Pagination for shortcodes on single-pages
* @uses $woocommerce_loop;
add_action( 'woocommerce_after_template_part', 'kli_wc_shortcode_pagination' );
function kli_wc_shortcode_pagination( $template_name ) {
if ( ! ( $template_name === 'loop/loop-end.php' && is_page() ) ){
global $wp_query, $woocommerce_loop;
if ( ! isset( $woocommerce_loop['pagination'] ) ){
$wp_query->query_vars['paged'] = $woocommerce_loop['pagination']['paged'];
$wp_query->query['paged'] = $woocommerce_loop['pagination']['paged'];
$wp_query->max_num_pages = $woocommerce_loop['pagination']['max_num_pages'];
$wp_query->found_posts = $woocommerce_loop['pagination']['found_posts'];
$wp_query->post_count = $woocommerce_loop['pagination']['post_count'];
$wp_query->current_post = $woocommerce_loop['pagination']['current_post'];
// Custom pagination function or default woocommerce_pagination()
* Custom pagination for WooCommerce instead the default woocommerce_pagination()
* @uses plugin Prime Strategy Page Navi, but added is_singular() on #line16
remove_action('woocommerce_after_shop_loop', 'woocommerce_pagination', 10);
add_action( 'woocommerce_after_shop_loop', 'kli_woocommerce_pagination', 10);
function kli_woocommerce_pagination() {

This comment has been minimized.

jlr7245 commented Jun 25, 2015

This works great. Thanks!


This comment has been minimized.

nschoen commented Jul 18, 2015

Thanks a lot! Works great.

FYI: Our product permalink structure was /shop/%product_cat%. This led to some problems. The URL ending /page/2 was interpreted as a product and so I always got a 404 error. It took me a while to recognize this. Already tried around with add_rewrite_endpoint..

I changed it to /shop/%product_cat%/product and now its working :)


This comment has been minimized.

frankthetank1234567 commented Sep 4, 2015

Thanks a lot for this. Works perfect on pages!

Is there anyway to get this working on posts as well? Whenever I put the shortcode in one of my posts the pagination is not working. I really need to get it working soon. Any help would be greatly appreciated!


This comment has been minimized.

kubik101 commented Sep 9, 2016

I am using:

  • WooCommerce Version 2.6.4
  • WordPress Version 4.6.1

All I have done is inserted the above code into my functions.php file and inserted the following shortcode into my page
[sale_products per_page="3" columns="3"]

This has enabled paging to work by visiting the page with /page/2/
But no pagination navigation is showing.

How do I get the pagination navigation to show?


This comment has been minimized.

ChristianGiupponi commented Nov 14, 2016

If I add this code I get a lot of warning:

Notice: is_main_query è stato richiamato in maniera scorretta. In pre_get_posts, viene usato il metodo WP_Query->is_main_query() anziché la funzione is_main_query(). Si veda Leggi Debugging in WordPress per maggiori informazioni. (Questo messaggio è stato aggiunto nella versione 3.7.0.) in /home/vagrant/www/site/wp-includes/functions.php on line 3996

Notice: Undefined index: post_type in /home/vagrant/www/site/wp-content/themes/mytheme/inc/setup.php on line 246

Which means that is_main_query is used in wrong way

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment