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.

2
  • 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. Commented Nov 1, 2018 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 Commented Nov 1, 2018 at 16:13

1 Answer 1

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.