views:

201

answers:

1

My WordPress theme has a custom taxonomy called "Collections". The custom taxonomy is hierarchical, so there are subcollections.

I have a Collection called "Books" and a sub-collection called "Novels". There are some posts that are just in "Books", and some posts that are in "Novels". I want the page for the "Books" collection to only show posts in the main "Books" collection, not the ones in the "Novels" subcollection. But by default, WordPress includes posts in "subcollections" in the query for a taxonomy.

How do I exclude posts in child terms from my taxonomy query? This is easy with categories, but it seems there is no built in way to do this with custom taxonomies.


Update: Jan's solution worked perfectly. Here is the code I used, placed above the Loop in index.php:

// if is taxonomy query for 'collections' taxonomy, modify query so only posts in that collection (not posts in subcollections) are shown.
if (is_tax()) {
 if (get_query_var('collection')) {
  $taxonomy_term_id = $wp_query->queried_object_id;
  $taxonomy = 'collection';
  $unwanted_children = get_term_children($taxonomy_term_id, $taxonomy);
  $unwanted_post_ids = get_objects_in_term($unwanted_children, $taxonomy);

  // merge with original query to preserve pagination, etc.
  query_posts( array_merge( array('post__not_in' => $unwanted_post_ids), $wp_query->query) );
 }
}
+1  A: 

It seems the WP_Query class always includes all items of hierarchical taxonomies. If you want to counter this, you can use the same trick they use: get all subitems of your taxonomy item, then get all the post id's in those subitems, and then put them in the post__not_in parameter:

$unwanted_children = get_term_children($taxonomy_term_id, $taxonomy);
$unwanted_post_ids = get_objects_in_term($unwanted_children, $taxonomy);

This will result in a query that has AND posts.ID IN (1, 2, 3) AND posts.ID NOT IN (2, 3), which will return only this post with ID 1. Very unelegant, but it works.

Of course, if you go this route, you could also just pass the post id's you want, and tell the query nothing about the taxonomy.

How do you do this for categories? The query code seems to include children there too.

Jan Fabry
Thanks, this worked perfectly! With categories, you can use the "category__in" parameter, which doesn't include posts in child categories. Unfortunately Wordpress doesn't have an equivalent parameter for hierarchical custom taxonomies yet.
shipshape