Reputation: 175
I want to exclude all products/tours from the woocommerce category 'Excursions' (slug 'excursions-ru') on the 'Our tours' page (slug 'our-tours-ru'). Here is this page
I found this solution here So I use this code below, but it doesn't work for me.
Can't find where is my mistake.
add_filter( 'get_terms', 'get_subcategory_terms', 10, 3 );
function get_subcategory_terms( $terms, $taxonomies, $args ) {
$new_terms = array();
// if a product category and on the shop page
// to hide from shop page, replace is_page('YOUR_PAGE_SLUG') with is_shop()
if ( in_array( 'product_cat', $taxonomies ) && ! is_admin() && is_page('our-tours-ru') ) {
foreach ( $terms as $key => $term ) {
if ( ! in_array( $term->slug, array( 'excursions-ru' ) ) ) {
$new_terms[] = $term;
}
}
$terms = $new_terms;
}
return $terms;
}
Upvotes: 3
Views: 2649
Reputation: 253784
Update 1 (see below)
The
get_terms
filter hook is not made to filter products, so not convenient in your case.
Woocommerce has 3 dedicated hooks to make customizations on the product query (filter the products):
woocommerce_product_query
(action hook)woocommerce_product_query_meta_query
(filter hook)woocommerce_product_query_tax_query
(filter hook)We will use the last one as it's the best one for your case.
Now to make this active only for a specific page, we will use WordPress is_page()
conditional tag:
add_filter( 'woocommerce_product_query_tax_query', 'custom_exclude_products', 50, 2 );
function custom_exclude_products( $tax_query, $query ) {
// Only on a specific page
if( is_page('our-tours-ru') ){
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array('excursions-ru'),
'operator' => 'NOT IN'
);
}
return $tax_query;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Update:
As this is on a page, you are certainly using a Woocommerce shortcodes to display products on this particular page.
So in this case there is a dedicated hook for Woocommerce shortcodes:
add_filter( 'woocommerce_shortcode_products_query', 'custom_shortcode_exclude_products', 50, 3 );
function custom_shortcode_exclude_products( $query_args, $atts, $loop_name ){
if( is_page('our-tours-ru') ){
$query_args['tax_query'] = array( array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'excursions-ru' ),
'operator' => 'NOT IN'
) );
}
return $query_args;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works… It should also work for you.
You need to be sure that this products are shown on a Wordpress PAGE which slug is 'our-tours-ru', because if not no answer will work for you.
Last possibility that will work on mostly all cases, using pre_get_posts
filter:
add_filter( 'pre_get_posts', 'custom_query_exclude_products', 900, 1 );
function custom_query_exclude_products( $query ) {
if ( is_admin() || is_search() ) return $query;
if ( is_page('our-tours-ru') ){
$query->set( 'tax_query', array( array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'excursions ru' ),
'operator' => 'NOT IN'
) ) );
}
remove_action( 'pre_get_posts', 'custom_query_exclude_products' );
return $query;
}
Code goes in function.php file of your active child theme (or active theme).
Upvotes: 4
Reputation: 15620
(Since none of the existing answers works for you and that you're using a child theme, I posted this answer which is specific to the Entrada theme which you currently use on your site.)
The "Our Tours" page, as I could see it, is using the "Listing Full Width (three column grid)" template, which in the parent theme, it's located at entrada/entrada_templates/listing-full-width-3column-grid.php
, and which uses this template part: entrada/template-parts/grid-threecolumn.php
.
If you open it, you'd see this custom query:
$args = array(
'post_type' => 'product',
'posts_per_page' => $posts_per_page,
'paged' => 1
);
$args = entrada_product_type_meta_query($args, 'tour' );
$loop = new WP_Query( $args );
which is being used for the primary products section/grid on the "Our Tours" page.
So one easy way (and would likely work) for you to exclude the "Excursions" category from that query, or to exclude products from that category, is by copying entrada/template-parts/grid-threecolumn.php
to the child theme folder (i.e. entrada-child-picpic-v1_0/template-parts/grid-threecolumn.php
) and then customize the $args
array anyway you like. And for your question, try adding this before/above the $loop = new WP_Query( $args );
:
wp_reset_query(); // Just in case.
if ( is_page( 'our-tours-ru' ) ) {
if ( ! isset( $args['tax_query'] ) ) {
$args['tax_query'] = array();
}
// Excludes products from the "Excursions" category.
$args['tax_query'][] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'excursions-ru' ),
'operator' => 'NOT IN',
);
}
Note: That's the same tax_query
used in the other answers, except the one above is specifically for the listing-full-width-3column-grid.php
template (or any other page templates using the grid-threecolumn.php
template part).
Upvotes: 1
Reputation: 1502
To remove the specific category from specific page, Please pass the page id in place of YOUR_PAGE_ID , and put the below code in your current themes functions.php file.
add_filter( 'get_terms', 'exclude_category_from_specific_page', 10, 3 );
function exclude_category_from_specific_page( $terms, $taxonomies, $args ) {
$new_terms = array();
// if a product category and on a page
if ( in_array( 'product_cat', $taxonomies ) && ! is_admin() && is_page('YOUR_PAGE_ID')) {
foreach ( $terms as $key => $term ) {
// Enter the name of the category you want to exclude
if ( ! in_array( $term->slug, array( 'excursions-ru' ) ) ) {
$new_terms[] = $term;
}
}
$terms = $new_terms;
}
return $terms;
}
To remove product from specific category use below code
/** * This code should be added to functions.php of your theme **/
add_filter( 'pre_get_posts', 'custom_pre_get_posts_query' );
function custom_pre_get_posts_query( $q ) {
if ( ! $q->is_main_query() ) return;
if ( ! is_page('YOUR_PAGE_ID') ) return;
$q->set( 'tax_query', array(array(
'taxonomy' => 'product_cat',
'field' => 'excursions-ru',
'terms' => array( 'excursions ru' ),
'operator' => 'NOT IN'
)));
remove_filter( 'pre_get_posts', 'custom_pre_get_posts_query' );
}
I hope it will help you. Thanks
Upvotes: 1
Reputation: 333
Please try the code below for this
function custom_pre_get_posts_query( $q ) {
$tax_query = (array) $q->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'excursions-ru' ),
'operator' => 'NOT IN'
);
$q->set( 'tax_query', $tax_query );
}
add_action( 'woocommerce_product_query', 'custom_pre_get_posts_query' );
Upvotes: 1