18

I found this question:

Theres a way to use $query->set('tax_query' in pre_get_posts filter?

which seems to indicate that yes, you can alter the taxonomy query on taxonomy archives via pre_get_posts(). so i came up with

add_action('pre_get_posts', 'kia_no_child_terms' );

function kia_no_child_terms( $wp_query ) {  
  if( is_tax() ) {
     $wp_query->tax_query->queries[0]['include_children'] = 0;
  }
}

as well as

add_action('pre_get_posts', 'kia_no_child_terms' );

function kia_no_child_terms( $wp_query ) {
   if( is_tax() ) {
        $tax_query = $wp_query->get( 'tax_query' );
        $tax_query->queries[0]['include_children'] = 0;
    $wp_query->set( 'tax_query', $tax_query );  
    }    
}

to try to set the include_children parameter to false... and just about every combination of the two i can think of. so far however, the taxonomy archive is still showing the items in the child term

and the following test just seems to ADD the additional tax queries instead of overwriting them... which just confuses me.

function dummy_test( $wp_query){
$tax_query = array(
             'relation' => 'OR',
             array(
               'taxonomy' => 'tax1',
               'terms' => array( 'term1', 'term2' ),
               'field' => 'slug',
             ),
             array(
               'taxonomy' => 'tax2',
               'terms' => array( 'term-a', 'term-b' ),
               'field' => 'slug',
             ),
           );


$wp_query->set( 'tax_query', $tax_query );

);
add_action('pre_get_posts','dummy_test');

shouldn't SET overwrite the current value?

4
  • Please take a look at this answer. That should bring you further.
    – kaiser
    Feb 23, 2012 at 7:00
  • thanks, but that is pretty much what i have tried. var_dumps/print_rs of the $wp_query global are showing that new tax query in addition to the existing query instead of in place of... at least on my taxonomy page. Feb 23, 2012 at 15:52
  • Yea, that code is meant to add to the query.
    – kaiser
    Feb 23, 2012 at 16:05
  • so there is no way to adjust/override the existing query? b/c what i want is to change the include_children parameter Feb 23, 2012 at 16:11

5 Answers 5

27

I know this is an old question, but it is a bit confusing and hopefully will help someone. The reason that `$query->set doesn't work is because the query has already been parsed and now we need to also update the tax_query object also. Here is how I did it:

function my_tax_query( $query ) {
    $package_id = 12345;
    $tax_query = array(
        'taxonomy' => 'package_id',
        'terms'    => array( $package_id ),
        'field'    => 'slug',
        'operator' => 'IN',
    );
    $query->tax_query->queries[] = $tax_query; 
    $query->query_vars['tax_query'] = $query->tax_query->queries;
}
add_action( 'pre_get_posts', 'my_tax_query' );
3
  • Sweet!! I checked this out and was able to adapt your code to work for all taxonomies, which was the original question. +1 (i'd give you more upvotes if I could) May 3, 2013 at 3:07
  • I was surprised and assuaged to see that this method also works for date queries.
    – David
    Sep 9, 2014 at 18:13
  • mmm - this doesn't work fo me. Does it work in main query and/or is_search?
    – v3nt
    Jul 3, 2020 at 9:29
16

As of Wordpress 3.7 a new action named parse_tax_query was added exactly for this purpose.

function kia_no_child_terms($wp_query) {  
  $wp_query->tax_query->queries[0]['include_children'] = 0;
}
add_action('parse_tax_query', 'kia_no_child_terms');

This hook modifies the values of both query_vars and tax_query. Using the pre_get_posts method resulted in duplicate taxonomy queries, at least for me.

Prior to 3.7 you must use the pre_get_posts action instead, as detailed in the other answers.

2
  • In my case, this seems a bit too far reaching and has unintended side-effects... it prevents the submenus of my navigation from showing up.
    – Manu
    May 29, 2015 at 20:14
  • 2
    @Manu - you're completely correct. The example provided is very simplified and shows the relevant variables only. In a real-life scenario you would inspect $wp_query, use template tags, or both, or some other logic, to determine if the query should be modified in the first place.
    – leepowers
    May 29, 2015 at 20:21
5

I could not get this to work with any combination of pre_get_posts or parse_query. I can do it relatively easily by wiping out the query object after it is made. I don't like it because then I'm running the query twice, but I'm at my wit's end with trying to be "efficient."

function kia_no_child_taxonomies(){

    if(is_tax()){
        $args = array(
            'tax_query' => array(
                array(
                    'taxonomy' => get_query_var('taxonomy'),
                    'field' => 'slug',
                    'terms' => get_query_var('term'),
                    'include_children' => FALSE
                )
            )
        );
        query_posts($args); 
    }
}

 add_action('wp','kia_no_child_taxonomies');

So until someone comes along with a better answer, this is the only method I have found so far.

EDIT:

Adapting the answer from @Tanner Moushey, I was finally able to make this work to exclude all child terms from a taxonomy archive on the pre_get_posts hook without the inefficient double-query.

function kia_no_child_taxonomies( $query ) {

    if( is_tax() ):

    $tax_obj = $query->get_queried_object();

   $tax_query = array(
                    'taxonomy' => $tax_obj->taxonomy,
                    'field' => 'slug',
                    'terms' => $tax_obj->slug,
                    'include_children' => FALSE
            );
   $query->tax_query->queries[] = $tax_query;
   $query->query_vars['tax_query'] = $query->tax_query->queries;

   endif;

}
add_action( 'pre_get_posts', 'kia_no_child_taxonomies' );
6
  • This is wrong. You should not use query_posts, use pre_get_posts or request instead.
    – kovshenin
    Aug 9, 2012 at 0:21
  • 1
    that's not helpful. why not post an answer then if you know how to make pre_get_posts work in this instance? i obviously posted in my question that i tried it, but came to the conclusion that you cannot modify the tax_Query object through that filter Aug 10, 2012 at 12:11
  • Sorry, should have been more helpful. So the real tax query is built (with parse_tax_query) after pre_get_posts is fired, and in an actual WP_Tax_Query, which contains all tax queries combined from query variables (including the tax_query query var) so in your case it's parsing your tax_query query var, and then appending whatever else is available via query vars, such as category, tag__in, and others. You can use pre_get_posts to remove existing query vars prior to adding your own.
    – kovshenin
    Oct 10, 2012 at 9:15
  • Thanks for the better explanation. Obviously this is old, so I moved on with the solution I had. I never was able to modify the include_children parameter through the pre_get_posts hook. Ah well. Oct 10, 2012 at 13:16
  • Yeah I figured, haven't been here for a long time ;)
    – kovshenin
    Oct 10, 2012 at 14:09
2

For those who like me were stuck with this issue, I found something useful. I used the priority system

    function kia_no_child_taxonomies( $query ) {

if( is_tax() ):

$tax_obj = $query->get_queried_object();
$tax_query = array(
                'taxonomy' => $tax_obj->taxonomy,
                'field' => 'slug',
                'terms' => $tax_obj->slug,
                'include_children' => FALSE);
$query->tax_query->queries[] = $tax_query;
$query->query_vars['tax_query'] = $query->tax_query->queries;
return $query;
endif;

}
 add_action( 'pre_get_posts', 'kia_no_child_taxonomies',0 );

My query wasn't included in the result and search was broken with my exclusions. Hope this will help.

2

I stumbled upon the following thread on WP Core and am using it successfully to exclude children for a specific taxonomy:

function wpse_43181_parse_tax_query( $query ) {
  if ( ! empty( $query->tax_query->queries ) ) {
    foreach ( $query->tax_query->queries as &$tax_query ) {
      if ( $tax_query['taxonomy'] === 'your_taxonomy' ) {
        $tax_query['include_children'] = false;
      }
    }
  }
}
add_action( 'parse_tax_query', 'wpse_43181_parse_tax_query' );

Tweak it to your liking to exclude children from all taxonomy pages.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.