I would like to know if anyone has a clue on how to hide a specific product category all around my website. Means on the “shop”, “related product” and the “search” of my WordPress WooCommerce website.
For the “shop” pages I have done (and it’s working) the following:
function custom_pre_get_posts_q( $q ) { $tax_query = (array) $q->get( 'tax_query' ); $tax_query[] = array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => array( 'carton' ), // Don't display products in the composite category on the shop page. 'operator' => 'NOT IN' ); $q->set( 'tax_query', $tax_query ); } add_action( 'woocommerce_product_query', 'custom_pre_get_posts_q' );
For the search I tried the following but it doesn’t work:
function exclude_category_from_search($query) { if ($query->is_search) { $cat_id = get_cat_ID('carton'); $query->set('cat', '-'.$cat_id); } return $query; }
add_filter(‘pre_get_posts’,’exclude_category_from_search’);
Finally, for the related product I tried the following which seems deprecated since WC 3.x:
function wc_remove_related_products( $args ) { if (is_product() && has_term( 'carton', 'product_cat')) { return array(); } return $args; } add_filter('woocommerce_related_products_args','wc_remove_related_products', 10);
I also have in my child-theme the following:
` <?php foreach ( $related_products as $related_product ) : ?> <?php $post_object = get_post( $related_product->get_id() ); setup_postdata( $GLOBALS['post'] =& $post_object ); wc_get_template_part( 'content', 'product' ); ?> <?php endforeach; ?>`
And I know that we can hide product category with this part of code that I used on other classes:
global $post; $terms = wp_get_post_terms( $post->ID, 'product_cat' ); foreach ( $terms as $term ) $categories[] = $term->slug; if ( in_array( 'children', $categories ) ) {
Anyone have an idea on how to do that with the new version of WoomCommerce? I’ve made a lot of research around but all looks like deprecated answer since this new version.
PS: I need to keep this category as I am using it to create some composite products, so only hide these products but not remove them .
Cheers
Advertisement
Answer
To exclude your category (“Carton” here) from search and SHOP page, add the following in my function.php file of my child theme:
/* hide CARTON category SEARCH =============================*/ function sm_pre_get_posts( $query ) { if ( $query->is_search() ) { $query->set( 'post_type', array( 'product' ) ); $tax_query = array( array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => 'carton', //slug name of category 'operator' => 'NOT IN', ), ); $query->set( 'tax_query', $tax_query ); } } add_action( 'pre_get_posts', 'sm_pre_get_posts' ); /* hide CARTON category for SHOP pages ====================================*/ function custom_pre_get_posts_query( $q ) { $tax_query = (array) $q->get( 'tax_query' ); $tax_query[] = array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => array( 'carton' ), // Don't display products in the carton category on the shop page. 'operator' => 'NOT IN' ); $q->set( 'tax_query', $tax_query ); } add_action( 'woocommerce_product_query', 'custom_pre_get_posts_query' );
Regarding the “related products”, I had to tweak it but in the end it’s improving the related coming with woocommerce. I am basically sorting my related product by order of brand, category & season. Because “Carton” is a category, it doesn’t retrieve any of them:
global $post; $terms = get_the_terms( $post->ID, 'product_cat' ); foreach ($terms as $term) { $myTerm = $term->slug; if($myTerm == 'mens' || $myTerm == 'ladies'){ $mainCat = $myTerm; }else if($myTerm == 'accessories'){ $mainCat = $myTerm; }else if($myTerm == 'children'){ $mainCat = $myTerm; }else if($myTerm == 'summer' || $myTerm == 'winter'){ $seasonCat = $myTerm; } } $terms = get_the_terms( get_the_ID(), 'pa_brand' ); foreach ($terms as $term) { $theBrand = $term->slug; } ?> <div class="product-carousel related-products spb_content_element"> <div class="title-wrap clearfix"> <h3 class="spb-heading"><span><?php echo esc_attr($related_heading); ?></span></h3> <div class="carousel-arrows"><a href="#" class="carousel-prev"><i class="sf-icon-chevron-prev"></i></a><a href="#" class="carousel-next"><i class="sf-icon-chevron-next"></i></a></div> </div> <div class="related products carousel-items <?php echo esc_attr($gutter_class); ?> product-type-<?php echo esc_attr($related_product_display_type); ?>" id="carousel-<?php echo esc_attr($sf_carouselID); ?>" data-columns="<?php echo esc_attr($woocommerce_loop['columns']); ?>"> <?php $args = array( 'posts_per_page' => -1, 'tax_query' => array( array( 'taxonomy' => 'pa_brand', 'field' => 'slug', 'terms' => $theBrand ), array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => $mainCat ), array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => $seasonCat ) ), 'post_type' => 'product', 'orderby' => 'rand', 'order' => 'desc', 'posts_per_page' => 12 ); $loop = new WP_Query( $args ); if ( $loop->have_posts() ) { while ( $loop->have_posts() ) : $loop->the_post(); wc_get_template_part( 'content', 'product' ); endwhile; } else { echo __( 'No products found' ); } wp_reset_postdata(); ?> </div> </div>