Merkucio
Merkucio

Reputation: 175

Exclude products from a product category on a specific page in Entrada theme

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

Answers (4)

LoicTheAztec
LoicTheAztec

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

Sally CJ
Sally CJ

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

dineshkashera
dineshkashera

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

Yogesh Garg
Yogesh Garg

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

Related Questions