Search code examples
woocommercehook-woocommerce

Hide out of stock products in home page not in the catalog


I know how to hide the products from catalog since Woocommerce settings but i need to hide out of stock products in some pages, i have this code:

add_action( 'pre_get_posts', 'code_hide_out_of_stock_in_home' );
function code_hide_out_of_stock_in_home( $query ) {
    if( is_page( array( 5576, 6489, 2 ) ) ) {
        $query->set( 'meta_key', '_stock_status' ); 
        $query->set( 'meta_value', 'instock' );
    }
}

It works very well but for one reason in the pages that i apply the code my header menu disappears and i don't know why. I already know that the problem is in the code because when i hide the code my header menu appears again.

I need that the out of stock products don't appear in the specific pages


Solution

  • There are actually multiple queries running on each page. One of them is the query that fetches the menu items. With your custom pre_get_posts action you essentialy told WordPress to check whether those header menu items have instock value for _stock_status meta keys (and of course they don't).

    You should check whether the query is associated with product post type and only set your query parameters if it is:

    add_action( 'pre_get_posts', 'code_hide_out_of_stock_in_home' );
    function code_hide_out_of_stock_in_home( $query ) {
    
        // Only apply for 'product' post_type
        if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'product' ) {
    
            // Only on these page IDs
            if( is_page( array( 5576, 6489, 2 ) ) ) {
                $query->set( 'meta_key', '_stock_status' ); 
                $query->set( 'meta_value', 'instock' );
            }
        }
    }
    

    However, if you display those products using [products] shortcode, a better approach would be to use the woocommerce_shortcode_products_query filter, not the pre_get_posts action. Check this question and solution for more info.