0

Is this normal WordPress behaviour?

I have:

  • Custom post type: "article"
  • Custom taxonomy: "company" (hierarchical)

In the backend, when I go to the post list for "Articles", and constrain results by clicking on a "company" term, I expect to see only posts tagged with that specific company.

Instead, I see those plus posts tagged with its child companies as well.

Example: if I click my "AT&T" "company" term (9), I don't just see my "articles" tagged with "AT&T", but also those tagged with all downstream child terms across multiple descendent levels (42)...

  • AT&T
    • DirecTV
      • WarnerMedia
        • HBO
        • Turner Broadcasting
          • CNN

That doesn't feel like correct behaviour.

Here is how I register the "company" taxonomy...

/**
 * ==============================================================================
 *                      REGISTER TAXONOMY
 * ==============================================================================
 */

if ( ! function_exists( 'register_taxonomy_company' ) ) {

function register_taxonomy_company() {

  $labels = array(
        'name'                       => _x( 'Organisations', 'Taxonomy General Name', 'text_domain' ),
        'singular_name'              => _x( 'Organisation', 'Taxonomy Singular Name', 'text_domain' ),
        'menu_name'                  => __( 'Organisations', 'text_domain' ),
        'all_items'                  => __( 'All Organisations', 'text_domain' ),
        'parent_item'                => __( 'Parent Organisation', 'text_domain' ),
        'parent_item_colon'          => __( 'Parent Organisation:', 'text_domain' ),
        'new_item_name'              => __( 'New Organisation Name', 'text_domain' ),
        'add_new_item'               => __( 'Add New Organisation', 'text_domain' ),
        'edit_item'                  => __( 'Edit Organisation', 'text_domain' ),
        'update_item'                => __( 'Update Organisation', 'text_domain' ),
        'view_item'                  => __( 'View Organisation', 'text_domain' ),
        'separate_items_with_commas' => __( 'Separate Organisations with commas', 'text_domain' ),
        'add_or_remove_items'        => __( 'Add or remove Organisation', 'text_domain' ),
        'choose_from_most_used'      => __( 'Choose from the most used', 'text_domain' ),
        'popular_items'              => __( 'Popular Organisation', 'text_domain' ),
        'search_items'               => __( 'Search Organisation', 'text_domain' ),
        'not_found'                  => __( 'Not Found', 'text_domain' ),
        'no_terms'                   => __( 'No Organisation', 'text_domain' ),
        'items_list'                 => __( 'Organisations list', 'text_domain' ),
        'items_list_navigation'      => __( 'Organisations list navigation', 'text_domain' ),
        );
    $rewrite = array(
        'slug'                       => 'organisation',
        'with_front'                 => true,
        'hierarchical'               => true,
    );
        $args = array(
            'labels'                     => $labels, // as above
            'public'                     => true,
            'show_ui'                    => true,
            'show_in_nav_menus'          => true,
            'hierarchical'               => true,
            'show_admin_column'          => true,
        'single_value'               => false, // Use single-select radio button, only one Organisation per object
            'show_tagcloud'              => true,
            'rewrite'                    => $rewrite,  // as above
        );

    // Put it all together!
    register_taxonomy(
        /* taxonomy name */         'company',
        /* attach to object */  array( 'article','report','session','quote','post' ),
        /* arguments */                 $args
    );

}
add_action( 'init', 'register_taxonomy_company', 0 );

}

And this is how I register the "article" post type...

/* Register custom post type */

function cpt_article() {

    $labels = array(
        'name'                  => 'Articles',
        'singular_name'         => 'Article',
        'menu_name'             => 'Articles',
        'name_admin_bar'        => 'Article',
        'archives'              => 'Article Archives',
        'parent_item_colon'     => 'Parent Article:',
        'all_items'             => 'All Articles',
        'add_new_item'          => 'Add New Article',
        'add_new'               => 'Add New',
        'new_item'              => 'New Article',
        'edit_item'             => 'Edit Article',
        'update_item'           => 'Update Article',
        'view_item'             => 'View Article',
        'search_items'          => 'Search Article',
        'not_found'             => 'Not found',
        'not_found_in_trash'    => 'Not found in Trash',
        'featured_image'        => 'Featured Image',
        'set_featured_image'    => 'Set featured image',
        'remove_featured_image' => 'Remove featured image',
        'use_featured_image'    => 'Use as featured image',
        'insert_into_item'      => 'Insert into Article',
        'uploaded_to_this_item' => 'Uploaded to this Article',
        'items_list'            => 'Articles list',
        'items_list_navigation' => 'Articles list navigation',
        'filter_items_list'     => 'Filter Articles list',
    );
    $args = array(
        'label'                 => 'Article',
        'description'           => 'Articles.',
        'labels'                => $labels,
        'supports'              => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', /*'comments', 'revisions', 'post-formats',*/ ),
        'taxonomies'            => array( 'source', 'category', 'post_tag' ),
        'hierarchical'          => false,
        'public'                => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'menu_position'         => 6,
        'menu_icon'             => 'dashicons-media-text',
        'show_in_admin_bar'     => true,
        'show_in_nav_menus'     => true,
        'can_export'            => true,
        'has_archive'           => true,
        'exclude_from_search'   => false,
        'publicly_queryable'    => true,
        'capability_type'       => 'post',
    );
    register_post_type( 'article', $args );

}
add_action( 'init', 'cpt_article', 0 );

hierarchical had been set to true. I have changed it to false, but there is no effect.

UPDATE:

I have just checked another, separate WordPress install which runs hierarchical taxonomies and confirmed a second case - when viewing posts for a certain term, the WordPress admin post list seems to think it is appropriate behaviour to show posts for its sub-terms.

I can't believe that's correct.

Does anyone know a way to suppress this?

It makes it hard to manage things.

  • 1
    This is indeed correct behavior. Search around for parse_tax_query action, you need to ultimately modify the include_children argument for those queries. – Milo Nov 1 '18 at 15:25
  • @Milo Good pointer, thanks. Out of a handful of discussions, code in the answer at wordpress.stackexchange.com/a/202773/39300 seems to work - at least in the admin. Trying to understand the logic further, but it seems to be ... for each queried post in a taxonomy view, apply include_children=0 – Robert Andrews Nov 1 '18 at 16:13
0

As @Milo's pointer said, this:

  1. Sadly, is normal WordPress behaviour.
  2. Can be suppressed using parse_tax_query and include_children set at 0...

The code found in the answer at https://wordpress.stackexchange.com/a/202773/39300 Works for me...

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');
//  An empty $taxonomy_slugs array will exclude children for all taxonomy archives.

parse_tax_query fires at taxonomy time, include_children 0 is where I can deny children from appearing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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