Using FacetWP with Stock status and Catalog visibility settings
WooCommerce products have several “product status” fields and settings that are (or can be) used to determine if a product appears in the listing or not. Examples are the “Stock status” setting and the “Catalog visibility” setting, but there are more.
On this page, we will go through all caveats in using these fields and settings with FacetWP, because – depending on the type of product template you are using – not all of them will work out of the box.
On native WooCommerce product archive pages, most of these settings work as you’d expect. But on Listing Builder shortcode templates or pages with a custom WP_Query, you’ll need to make some customizations to get these settings to work with your template.
Another issue is that Search facets will not work automatically with the search-related “Catalog visibility” settings.
Product status and Catalog visibility settings
A short overview of the product status and visibility settings involved:
First, on product pages, there is the “Catalog visibility” setting in the right sidebar which determines if and where a product is visible. Under it, there is a “This is a featured product setting” to give products a “featured” status.
Next, a product can be in or out of stock, determined by the “Stock status” setting under Inventory in the product meta box:
Next, in the same meta box, a product can be set to be on sale, by entering a sales price. And products can gather reviews, resulting in a review rating between 1 and 5.
On a global level, under WooCommerce > Settings > Products > Inventory > Out of stock visibility, is the setting “Hide out of stock items from the catalog” with which you can exclude out-of-stock products from the listing entirely, overruling the individual “Catalog visibility” setting:
All of these settings are stored in their own particular way. To be able to customize and fix WooCommerce product and search queries in all possible template situations, we need to know exactly how they are stored and treated under the hood. Below, we added a reference of all settings involved.
Using WooCommerce product archive pages
If you are using FacetWP on a native WooCommerce product archive (like your Shop page), the above product status settings will all work as you’d expect with FacetWP. There is one exception: Search facets will not honor the “Catalog visibility” settings. See the fix below.
Out-of-stock products and indexing
The global WooCommerce setting “Hide out of stock items from the catalog” is disabled by default, resulting in out-of-stock products being shown in the listing:
However, FacetWP does not index them by default. You can make FacetWP index out-of-stock products by enabling the “Index out-of-stock products” setting under FacetWP > Settings > Woocommerce.
If you don’t want out-of-stock products included in your product archive listing, enable “Hide out of stock items from the catalog” in the WooCommerce settings, and disable FacetWP’s “Index out-of-stock products” setting.
Note that the “Hide out of stock items from the catalog” setting only works for native WooCommerce product archive pages, not on Listing Builder templates:
Using Listing Builder product templates
If you are using a Listing Builder listing template with a products
query, all “Catalog visibility” settings will be ignored.
Also the global WooCommerce setting “Hide out of stock items from the catalog” (under WooCommerce > Settings > Products > Inventory > Out of stock visibility) will be ignored, which means that the listing will always show out-of-stock products, no matter the setting.
To let facets work correctly with this setup, FacetWP’s “Index out-of-stock products” setting (under FacetWP > Settings > WooCommerce) needs to be enabled, otherwise there will be no facet choices for out-of-stock products.
If you want the Listing Builder query to honor any of the “Catalog visibility” settings (or other product status values), you’ll need to narrow the query with a query filter setting, or add a tax_query
in “Dev mode”:
Fix Catalog visibility or stock status in Listing Builder queries
To let your Listing Builder query honor any of the “Catalog visibility” settings (other than “Shop and search results”), or the “Out of stock” setting, you’ll need to use a query filter.
For example, to show only products that are in stock, click “Add query filter”, select the “Product visibility” taxonomy, and set its terms to be NOT IN
outofstock
:
See the reference below for all terms that are available in the product_visibility
, and how they relate to the “Catalog visibility” settings and stock status.
If you need more flexibility, you can also switch the Query tab to “Dev mode”, and add a tax_query
that filters by terms from the product_visibility
taxonomy. To do the same as in above query filter, use the following arguments:
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
<?php return [ "post_type" => [ "product" ], "post_status" => [ "publish" ], "tax_query" => [ [ "taxonomy" => "product_visibility", "field" => "name", "operator" => "NOT IN", "terms" => [ "outofstock" ] ] ], "posts_per_page" => 10 ];
Note that if you filter out out-of-stock products like this, you’ll also need to disable FacetWP’s “Index out-of-stock products” setting (under FacetWP > Settings > WooCommerce).
You can adapt the above code to filter the query by any of the other product_visibility terms. For example, if you want to mimic “normal” WooCommerce archive behavior, by filtering out “Hidden” products and products with “Search results only”, you’ll need to filter by exlude-from-catalog
:
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
<?php return [ "post_type" => [ "product" ], "post_status" => [ "publish" ], "tax_query" => [ [ "taxonomy" => "product_visibility", "field" => "name", "operator" => "NOT IN", "terms" => [ "exclude-from-catalog" ] ] ], "posts_per_page" => 10 ];
To combine this with filtering out out-of-stock products, you’ll need to add an AND
relationship in the tax_query
argument:
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
<?php return [ "post_type" => [ "product" ], "post_status" => [ "publish" ], "tax_query" => [ 'relation' => 'AND', [ "taxonomy" => "product_visibility", "field" => "name", "operator" => "NOT IN", "terms" => [ "exclude-from-catalog" ] ], [ "taxonomy" => "product_visibility", "field" => "name", "operator" => "NOT IN", "terms" => [ "outofstock" ] ] ], "posts_per_page" => 10 ];
Using the WooCommerce loop in the Listing Builder in dev mode
If you use a WooCommerce loop template or PHP include in the Listing Builder’s Display tab (in “Dev mode”), there will be even more issues. In this case, the native WooCommerce product loop will honor the “Stock status” and “Catalog visibility” settings (like on a native WooCommerce archive page), but the facets will not. This will lead to issues with facet counts being off, and Pager facets showing the wrong numbers of products, pages, and result counts.
The fix for these issues is the same as for other Listing Builder listings.
Using custom product queries
If you are using a custom WP_Query
to fetch products, all of the above issues in Listing Builder queries will happen here too. You can fix it by adding the same tax_query
to the query arguments:
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
$args = array( 'post_type' => 'product', 'post_status' => 'publish', 'tax_query' => array( 'relation' => 'AND', array( 'taxonomy' => 'product_visibility', 'field' => 'name', 'terms' => array( 'exclude-from-catalog' ), 'operator' => 'NOT IN', ), array( 'taxonomy' => 'product_visibility', 'field' => 'name', 'terms' => array( 'outofstock' ), 'operator' => 'NOT IN', ) ), 'posts_per_page' => 10 );
Fix Catalog visibility settings in Search facets
The “Catalog visibility” settings also influence if a product appears in search results or not. These settings are intended to work only on WooCommerce product search result pages (pages with the URL: /?s=keyword&post_type=product
).
These settings will not work out of the box with Search facet results, on any template that queries products.
If you are using a native WooCommerce product archive, the “Hidden” setting will work when using the facet, but the “Shop only” setting not. In Listing Builder templates and custom product queries, none of the “Catalog visibility” will have any influence on Search facet results.
To fix this, add the following code to your (child) theme’s functions.php. It will exclude products from the Search facet’s results that have the exclude_from_search
term set in the product_visibility
taxonomy. This is the case when you set “Catalog visibility” to “Shop only” or “Hidden” (see this setting behavior overview).
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_filter( 'facetwp_search_query_args', function( $search_args, $params ) { $search_args['tax_query'] = array( array( 'taxonomy' => 'product_visibility', 'field' => 'name', 'terms' => 'exclude-from-search', // Is true if "Catalog visibility" is set to "Shop only" or "Hidden". 'operator' => 'NOT IN', ), ); return $search_args; }, 10, 2 );
Combined with the above tax_query filter this basically mimics the “normal” WooCommerce behavior on product search pages. With one exception: the “search results only” setting will not work, because Search facets dynamically filter products that were there in the first place.
Create a stock status facet
A product’s stock status can be set to three options:
As you can see in the stock status reference table below, the value of this setting is stored in three ways. So if you want to create a facet that displays stock status choices, you have a few options for its Data Source field.
If you choose the field “Stock Status” (under the “WooCommerce” heading in the dropdown), the facet will be able to display only two choices: “In Stock”, and Out of Stock”. Products that have their Stock status set to “On backorder” will be considered “In Stock”.
If you choose the field “_stock_status” (under the “Custom Fields” heading in the dropdown), the facet will be able to display all three possible values of the setting: instock
, outofstock
, and onbackorder
.
To make these labels readable for users, you can use the facetwp_facet_display_value hook:
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_filter( 'facetwp_facet_display_value', function( $label, $params ) { if ( 'my_stock_status_facet' == $params['facet']['name'] ) { // Replace 'my_stock_status_facet' with the name of your stock status facet if ( 'instock' == $label ) { $label = 'In Stock'; } if ( 'outofstock' == $label ) { $label = 'Out of Stock'; } if ( 'onbackorder' == $label ) { $label = 'On Backorder'; } } return $label; }, 10, 2 );
In both types of facets, the “Out of Stock” choice will only show up if the global WooCommerce setting “Hide out of stock items from the catalog” is disabled:
Also, FacetWP must be set to index out-of-stock products. You can enable this under FacetWP > Settings > WooCommerce > “index out-of-stock products?”.
WooCommerce product status reference
To be able to customize and fix WooCommerce product and search queries in all possible template situations, we need to know exactly how the various product visibility and status settings are stored and treated under the hood. Some of them, like stock status and review rating, are even stored in more than one place:
Product visibility taxonomy
First, there is the product_visibility
taxonomy, which stores values for “Catalog visibility” setings, the “Stock status” setting (only if “Out of stock” is selected), and the average, rounded product review ratings:
Taxonomy | Possible terms |
---|---|
product_visibility |
exclude-from-catalog exclude-from-search featured outofstock rated-1 rated-2 rated-3 rated-4 rated-5 |
A product’s “Catalog visibility” settings (and other custom field values) relate to the above product_visibility
terms as follows:
Setting | Terms set |
---|---|
Shop and search results | none |
Shop only | exclude-from-search |
Search results only | exclude-from-catalog |
Hidden | exclude-from-catalog andexclude-from-search |
This is a featured product | featured |
Inventory > Stock Status > Out of stock | outofstock |
(Average review rating) | rated-x where x is the rounded _average_rating custom field value, ranging from 0 to 5 . |
Custom fields and values
The stock status, average review rating, and on-sale status are stored/available in the following fields and values:
Custom field / value | Possible values |
---|---|
_stock_status |
instock outofstock onbackorder |
stock_status (“Stock Status” in custom field selector dropdowns*) |
In Stock Out of Stock |
_average_rating |
a numerical value with 2 decimals, ranging from 0.00 to 5.00 |
average_rating (“Average Rating” in custom field selector dropdowns*) |
a numerical value with 2 decimals, ranging from 0.00 to 5.00 |
on_sale (“On Sale” in custom field selector dropdowns*) |
On Sale . Is set if the product has a Sales price set. |
Stock status storage
A products’ “Stock status” setting relates to the above custom field values as follows:
Inventory > Stock status setting | _stock_status |
stock_status (“Stock Status”) |
product_visibility (term) |
---|---|---|---|
In stock | instock |
In Stock |
– |
Out of stock | outofstock |
Out of Stock |
outofstock |
On backorder | onbackorder |
In Stock |
– |