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 );

See also