Using FacetWP with the WooCommerce [products] shortcode
With the WooCommerce [products] shortcode it’s easy to add a products/shop grid or list to any normal WordPress page.
The [products]
shortcode comes with a range of possible attributes to customize the products query, like the number of posts per page, the order, or category. You can also change the product grid’s appearance, like the number of columns, or add native WooCommerce pagination and sorting.
This shortcode will not work with FacetWP out of the box. To be able to use it on pages with facets, add the following code to your (child) theme’s functions.php. The code adds a custom facetwp
attribute to the shortcode and fixes several incompatibilities with FacetWP:
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
// Processes the shortcode attributes if the 'facetwp' shortcode attribute is present add_filter( 'shortcode_atts_products', function( $out, $pairs, $atts, $shortcode ) { if ( $shortcode == 'products' && in_array( 'facetwp', $atts ) ) { $out['facetwp'] = true; $out['class'] = 'facetwp-template'; $out['cache'] = false; // Bust WooCommerce caching } return $out; }, 10, 4 ); // Adds query arguments for FacetWP add_filter( 'woocommerce_shortcode_products_query', function( $query_args, $attributes ) { if ( isset( $attributes['facetwp'] ) ) { $query_args['facetwp'] = true; $query_args['wc_query'] = 'product_query'; // Optionally set 'posts_per_page' (or use the products shortcode's 'limit' attribute) // $query_args['posts_per_page'] = 8; // Optionally set 'orderby' and 'order' (or use the products shortcode's 'orderby' attribute) // $query_args['orderby'] = 'date'; // $query_args['order'] = 'DESC'; } return $query_args; }, 10, 2 ); // Fixes pagination incompatibilities add_filter( 'woocommerce_shortcode_products_query_results', function( $results, $shortcode ) { $attributes = $shortcode->get_attributes(); if ( isset( $attributes['facetwp'] ) && $attributes['paginate'] == false ) { $count = count( $results->ids ); $results->total = $count; $results->total_pages = 1; $results->current_page = 1; } elseif ( isset( $attributes['facetwp'] ) && $attributes['paginate'] == true ) { $results->total = FWP()->facet->query->found_posts; $results->total_pages = FWP()->facet->query->max_num_pages; } return $results; }, 10, 2 );
With this code in place, you can now use the [products]
shortcode on a page with facets, by setting the facetwp
attribute, as follows:
How to use shortcodes?
Shortcodes can be placed directly in post/page edit screens. You can also add them in text/HTML widgets. The WordPress Block Editor has a Shortcode block to place them in. And most Page builders have a dedicated shortcode module/widget. In PHP templates, shortcodes can be displayed with WP's do_shortcode() function:
echo do_shortcode('[my-shortcode]');
. More info[products facetwp]
Set the number of products
To change the number of products to show, you can use the limit
attribute, like this:
How to use shortcodes?
Shortcodes can be placed directly in post/page edit screens. You can also add them in text/HTML widgets. The WordPress Block Editor has a Shortcode block to place them in. And most Page builders have a dedicated shortcode module/widget. In PHP templates, shortcodes can be displayed with WP's do_shortcode() function:
echo do_shortcode('[my-shortcode]');
. More info[products facetwp limit="8"]
Alternatively, you can set the posts_per_page
query argument in line 18 of the above code, or use a pre_get_posts
filter.
Change the product order
To change the product order, you can use the orderby
attribute, like this:
How to use shortcodes?
Shortcodes can be placed directly in post/page edit screens. You can also add them in text/HTML widgets. The WordPress Block Editor has a Shortcode block to place them in. And most Page builders have a dedicated shortcode module/widget. In PHP templates, shortcodes can be displayed with WP's do_shortcode() function:
echo do_shortcode('[my-shortcode]');
. More info[products facetwp limit="8" orderby="date"]
See the [products]
shortcode’s documentation for all valid ordering options.
Alternatively, you can set the orderby
and order
query arguments in line 20-21 of the above code, or use a pre_get_posts
filter.
You can also set the default order using WooCommerce’s “Default product sorting” option. However, be aware that only two of those options will work with Sort facets.
Use a Pager and/or Sort facet
The above code will work with a Pager facet and/or Sort facet.
If the Sort facet does not work, make sure that you have set one of the two supported default WooCommerce sort options in the Customizer’s “Default product sorting” setting. If you want to use any of the other “Default product sorting” options, you’ll have to use WooCommerce’s own sorting dropdown instead of a Sort facet:
Use WooCommerce pagination and/or sorting
If you want to use native WooCommerce pagination and sorting, you need to set the shortcode’s paginate
attribute to true
:
How to use shortcodes?
Shortcodes can be placed directly in post/page edit screens. You can also add them in text/HTML widgets. The WordPress Block Editor has a Shortcode block to place them in. And most Page builders have a dedicated shortcode module/widget. In PHP templates, shortcodes can be displayed with WP's do_shortcode() function:
echo do_shortcode('[my-shortcode]');
. More info[products facetwp limit="8" paginate="true"]
With this attribute set, WooCommerce’s native sorting dropdown and numbered pagination will appear above and below the results.
This sorting dropdown will work with FacetWP. But to make this pagination work, you’ll need to add the following code to your (child) theme’s functions.php, below the above integration code:
How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
add_action( 'wp_footer', function() { ?> <script> (function($) { $().on('facetwp-refresh', function() { if (!FWP.loaded) { setup_woocommerce_product_shortcode_pagination(); } }); function setup_woocommerce_product_shortcode_pagination() { // Intercept WooCommerce products shortcode pagination $().on('click', '.woocommerce-pagination a', function(e) { e.preventDefault(); var matches = $(this).attr('href').match(/product-page=(\d+)/); if (null !== matches) { FWP.paged = parseInt(matches[1]); FWP.soft_refresh = true; FWP.refresh(); } }); } })(fUtil); </script> <?php }, 100 );