Exclude Child Term Posts from Parent Term Archive

I have created a custom hierarchical taxomony and when viewing a taxonomy archive page would like to only display the posts that have been assigned to that term. This works fine on the child term pages, but the parent term pages display posts assigned to them AND any child terms.

I found a solution that solves this for categories by inserting the following link after the beginning of the loop:

Read More
<? if ((is_category()) && in_category($wp_query->get_queried_object_id())) { ?>

But I haven’t been able to find a similar solution that works for custom taxonomies.

I also tried:

function exclude_children($wp_query) {
    if ( isset ( $wp_query->query_vars['custom_taxomony'] ) ) {
        $wp_query->set('tax_query', array('include_children' => false));
    }
}  
add_filter('pre_get_posts', 'exclude_children'); 

But that does not seem to have any effect. So the question is, how do I do this?

Related posts

Leave a Reply

3 comments

  1. Okay, I’ve found an answer. Part of the issue was the missing array @goto10 mentioned, and the other part was that tax_query has required arguments. Here’s what I’m using so far:

    function exclude_children($wp_query) {
        if ( isset ( $wp_query->query_vars['custom_taxomony'] ) ) {
            $wp_query->set('tax_query', array( array (
                'taxonomy' => 'custom_taxonomy',
                'field' => 'slug',
                'terms' => $wp_query->query_vars['custom_taxonomy'],
                'include_children' => false
            ) )
        }
    }  
    add_filter('pre_get_posts', 'exclude_children'); 
    

    I’d prefer to be using a variable for taxonomy => custom_taxonomy rather than hard coding the value in as that seems like a more reusable solution, but I don’t know how to pull the values from the WP_Tax_Query object.

    The important takeaway from this is that taxonomy, field, and terms are all required values, though that’s not clear from the Codex.

  2. An empty $taxonomy_slugs array will exclude children for all taxonomy archives.

    function taxonomy_archive_exclude_children($query){
       $taxonomy_slugs = ['product_category', 'application_category'];
       if($query->is_main_query() && is_tax($taxonomy_slugs)){
          foreach($query->tax_query->queries as &$tax_query_item){
            if(empty($taxonomy_slugs) || in_array($tax_query_item['taxonomy'], $taxonomy_slugs)){
                $tax_query_item['include_children'] = 0;
            }
          }
       }
     }
     add_action('parse_tax_query', 'taxonomy_archive_exclude_children');
    
  3. I used query_posts() to achieve this:

    $args = array(
        'post_type' => 'custom_post_type',
        'posts_per_page' => -1,
        'post_status' => 'publish',
        'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1), // Required if using pagination
        'tax_query' => array(
            array(
                'taxonomy' => 'custom_taxonomy',
                'field' => 'slug',
                'terms' => $term,
                'include_children' => false
            )
        )
    );
    
    query_posts( $args );
    

    Then your loop …

    if ( have_posts() ) :  while ( have_posts() ) : the_post();
    
        // Your loopy stuff
    
    endwhile;
    
    // Include your pagination ...
    
    the_posts_pagination(); // Or whatever you prefer
    
    endif; wp_reset_query();
    

    As @Sam said, taxonomy, field, and terms are all required for tax_query() (this tripped me up).