You want to show 24 items on shop and category pages, and also be able to skip paging with one click
It seems difficult to get any information about this and it took me some time to figure it out, therefore I thought that an article on that would be helpful for others.
The situation:
You have a shop build on WooCommerce with various product categories.
In the front-end customers can view the shop page and category pages.
The shop page is the default WooCommerce shop page you can define in the settings.
The category pages are links to the product categories.
Let’s say you are selling sport items. The categories could be “Tennis”, “Swimming” .. etc.. and the shop page would show all those categories on one page.
Now you need 2 features:
- Have 24 articles shown at once on shop page and category pages, with paging if more items are available
- Have a link next to the paging that allows you to skip paging and show all articles at once
This seems pretty straight forward and WooCommerce has all the hooks for that…
The issue:
loop_shop_per_page doesn’t always seem to work on category pages.
The solution:
The hook
add_filter('loop_shop_per_page', 'my_product_page'); function my_product_page( $cols ){ return 24; }
might work for the shop page. If you have issues with that, you can still go directly into the plugin file:
woocommerce/includes/class-wc-query.php
and change this
// Work out how many products to query. $q->set( 'posts_per_page', $q->get( 'posts_per_page' ) ? $q->get( 'posts_per_page' ) : apply_filters( 'loop_shop_per_page', wc_get_default_products_per_row() * wc_get_default_product_rows_per_page() ) );
into this
// Work out how many products to query. $q->set( 'posts_per_page', 24 );
but this will probably not affect the category pages at all.
The solution is to use a different hook inside your theme’s functions.php
function change_product_query($query) { $query->set( 'posts_per_page', 24 ); } add_action( 'pre_get_posts', 'change_product_query' );
With this we have the first part of our task solved!
We also want to have a button which allows us to skip paging and show all products at once (be aware that this might be dangerous for too many products. You don’t want your site to freeze, but you can use it for up to 500 items in my opinion).
So, first copy the file from the woocommerce plugin
plugins/templates/loop/pagination.php
and paste it into your theme folder here:
themes/your-theme/woocommerce/loop/pagination.php
Now, edit the nav element so that it looks something like this:
<nav class="woocommerce-pagination"> <?php echo paginate_links( apply_filters( 'woocommerce_pagination_args', array( // WPCS: XSS ok. 'base' => $base, 'format' => $format, 'add_args' => false, 'current' => max( 1, $current ), 'total' => $total, 'prev_text' => '←', 'next_text' => '→', 'type' => 'list', 'end_size' => 3, 'mid_size' => 3, ) ) ); ?> <?php if (is_paged()) : ?> <div style="float: left"><a class="button view-all" href="../../?view=all">View All</a></div> <?php else: ?> <div style="float: left"><a class="button view-all" href="?view=all">View All</a></div> <?php endif; ?> </nav>
Save and go back to your functions.php
We are now going to slightly improve our hook to capture the “view all” feature:
function change_product_query($query) { if($_GET['view'] === 'all'){ $cols = 9999; } else { $cols = 24; } $query->set( 'posts_per_page', $cols ); } add_action( 'pre_get_posts', 'change_product_query' );
I have set $cols to 9999 here, but as mentioned before, be careful and test in case you really have a lot of products. You don’t want your customers to sit in front of a frozen screen..
I hope this was helpful. Please tell me your thoughts.
AML says
Thank you so much for this! I was about to go insane trying to figure this out.
jerome says
Hi Adam,
my pleasure! Glad I could help, knowing how frustrating it can be…