Hide child term posts on parent term pages

I think that the best solution is to hook into the pre_get_posts action hook. First, it is checked if we are in an archive of your custom taxonomy, then set include_children to false for the tax_query argument of the query.

add_action( 'pre_get_posts', 'cyb_pre_get_posts' );
function cyb_pre_get_posts( $query ) {
    //Assuming the slug of the custom taxonomy is company-category
    //change it with the correct value if needed
    if( $query->is_tax( 'company-category' ) && $query->is_main_query() && !is_admin() ) {
        $tax_query = array(
            array(
                'taxonomy'         => 'company-category',
                'terms'            => $query->get( 'company-category' ),
                'include_children' => false
        );
        $query->set( 'tax_query', $tax_query );
    }
}

Another approach that seems better (taken from this answer and adapted for custom taxonomy instead of core category taxonomy):

add_filter( 'parse_tax_query', 'cyb_do_not_include_children_in_company_category_archive' );
function cyb_do_not_include_children_in_company_category_archive( $query ) {
    if ( 
        ! is_admin() 
        && $query->is_main_query()
        && $query->is_tax( 'company-category' )
    ) {
        $query->tax_query->queries[0]['include_children'] = 0;
    }
}

For custom queries and secondary loops (see WP_Query):

 $args = array(
             //Rest of you args go here
             'tax_query' => array(
                  array(
                      'include_children' => false
                  )
              )
          );

 $query = new WP_Query( $args );

Leave a Comment