Cross-posting your WooCommerce products to Google or Bing via their Merchant Centers is a fantastic way to increase your catalog’s visibility online. But, sometimes, you’re going to want to keep some of the products to yourself and leave them out of your product data feed. That’s where filters can come in handy. But, knowing how to filter WooCommerce products from your Google product data feed and getting them to suppress the right products can be a challenge.
Maybe you’re running a flash sale and, by the time Google gets the product indexed and into its feeds, the item will be long gone. Maybe you’re bound by contracts with manufacturers that say they have the sole rights to list those products with the search engines directly. Maybe it’s something Google themselves disapprove of. With the spread of CBD products in the last year or two, there has been a lot of this going around in the world of over-the-counter supplements.
Whatever the case may be, the WooCommerce Google Product Feeds plugin is a solid choice for the basic functionality. There is one major caveat – as of 3/1/2020, the plugin does not support feed-by-feed suppression. Thankfully, there are filters in the right places to be able to create a solution. This is something we had to do for a client a while back as part of re-launching their website.
For this tutorial, company names and industries have been changed out of respect for our client and we’ll be using a Wargaming-related substitute. Here’s how to filter WooCommerce products from your Google product data feed:
Step 1: Provide Form Controls
With our form implementation, we chose to extend the Product Data meta-box to include a section for feed suppression. We did this by putting the following functions into the functions.php file:
function mind_new_product_tab( $tabs ) { $tabs['merchant_feed'] = array( 'label' => 'Merchant Feeds', 'priority' => 99, 'target' => 'mind_merchant_feeds' ); return $tabs; } function mind_new_product_tab_content() { echo '<div id="mind_merchant_feeds" class="panel woocommerce_options_panel">'; echo '<p>Use the checkboxes below to hide this product from the following feeds:</p>'; woocommerce_wp_checkbox(array( 'id' => '_mind_hide_google', //'wrapper_class' => 'show_if_simple', 'label' => 'Google', 'description' => 'HIDE this product from the "Google" merchant feed.', 'default' => '0', 'desc_top' => false, '' )); woocommerce_wp_checkbox(array( 'id' => '_mind_hide_googleinv', //'wrapper_class' => 'show_if_simple', 'label' => 'Google Inventory', 'description' => 'HIDE this product from the "Google Inventory" merchant feed.', 'default' => '0', 'desc_top' => false, )); woocommerce_wp_checkbox(array( 'id' => '_mind_hide_bing', //'wrapper_class' => 'show_if_simple', 'label' => 'Bing', 'description' => 'HIDE this product from the "Bing" merchant feed.', 'default' => '0', 'desc_top' => false, )); echo '</div>'; } add_filter( 'woocommerce_product_data_tabs', 'mind_new_product_tab' ); add_filter( 'woocommerce_product_data_panels', 'mind_new_product_tab_content' );
When uploaded and refreshed, it should look something like the image below. Our client isn’t using all the available feeds. So, if using the code above, you will have a third option as opposed to this image’s two:
Step 2: Save Form Controls
Thanks to the woocommerce_process_product_meta filter, we need only 2 lines of code per checkbox in order to save the status of each one. These can also be added to functions.php.
Theoretically, it could be condensed down to a single line, but, as a college professor I admire greatly put it, “It is twice as difficult to debug as it is to code. Therefore, if you code as cleverly as you possibly can, then you are, by default, too stupid to debug it”.
Putting it on 2 lines helps with readability and maintenance on down the line and for a performance hit that is less than negligible. It should look something like this:
function mind_save_product_feed_suppression_settings( $post_id ){ $woo_checkbox = isset( $_POST['_mind_hide_google'] ) ? 'yes' : 'no'; update_post_meta( $post_id, '_mind_hide_google', $woo_checkbox ); $woo_checkbox = isset( $_POST['_mind_hide_googleinv'] ) ? 'yes' : 'no'; update_post_meta( $post_id, '_mind_hide_googleinv', $woo_checkbox ); $woo_checkbox = isset( $_POST['_mind_hide_bing'] ) ? 'yes' : 'no'; update_post_meta( $post_id, '_mind_hide_bing', $woo_checkbox ); } add_action( 'woocommerce_process_product_meta', 'mind_save_product_feed_suppression_settings' );
Step 3: Filter the Feed Itself
Now that individual products contain the necessary settings, it’s time to tie it all up. The woocommerce_gpf_exclude_product filter is the one that runs to decide if a product should appear in the feeds or not. It can also be placed in functions.php.
Like all filters this one can be chained, so be sure to obey the passed-in ‘excluded’ variable unless you want yours to be able to reinstate a product! Within our example, it should look something like this:
function mind_feed_filter($excluded, $product_id, $feed_format) { # Note: Return TRUE to exclude a product, FALSE to include it, $excluded to use the default behaviour. $suppress = false; switch($feed_format){ case 'google': $meta = get_post_meta($product_id,'_mind_hide_google',true); break; case 'googleinventory': $meta = get_post_meta($product_id,'_mind_hide_googleinv',true); break; case 'bing': $meta = get_post_meta($product_id,'_mind_hide_bing',true); break; default: return $excluded; break; } # If the checkbox is checked, suppress. if($meta == 'yes'){ $suppress = true; } # If 'Excluded' is set, suppress. if($excluded){ $suppress = true; } return $suppress; } add_filter( 'woocommerce_gpf_exclude_product', 'mind_feed_filter', 11, 3);
Not a Comprehensive Solution, But a Good Start
Please be aware – this is not intended to be a comprehensive solution. Instead, it’s meant to be a demonstration of extending the WooCommerce Google Product Feeds plugin. It doesn’t support suppressing Variations individually, for example. And, it doesn’t support all of the feeds that WooCommerce Google Product Feeds supports. Should we decide to flesh out the functionality and release a proper plugin, we would include it then. But, for the time being, implementing those changes is left as an exercise for the reader.