Support » Fixing WordPress » Custom taxonomy query that excludes children posts

  • I have been looking through the codex and forums and have not been successful in finding a solution. I feel like I am so close, but then again, I could be wrong.

    I am querying to get a list of posts that are of a custom type (document-tutorial) that are in a custom taxonomy (document-category).

    I can produce a list that matches but it includes posts that are in the children document-category but not not in the parent.

    Example: Document Category of “Windows” has sub-cats of “Windows XP”, “Windows Vista” and “Windows 7”. When I ask for ones in “windows” I am getting items that are in the children categories.

    I know this is a default behavior (at least that seems to be what I found), but I want to exclude the posts that are in children cats.

    I have 2 code chunks that I have tried. This example produces a result that is as described above (everything in “parent-category” and its children).

    $wpq = array(
                'post_type' => 'document-tutorial',
    			'taxonomy' => 'document-category',
                'term' => $doc->slug,
               'orderby'  => 'title',
               'order'=>ASC,
               'posts_per_page'=>-1,
                  );

    This is passed to $docposts = new WP_Query ($wpq); and then process through the loop. I can see if I pull the “request” element that the resulting SQL query has the array of taxonomy_term_id’s that are the parent and its children. It looks like this:
    SELECT wp_posts.* FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (39,40,41,42) ) AND wp_posts.post_type = 'document-tutorial' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_title ASC

    I would love to be able to pass in those ID’s and it should in theory solve it. So, I attempted a different request that uses a tax_query argument as per here – http://codex.wordpress.org/Function_Reference/query_posts#Taxonomy_Parameters

    That code looks like this:

    $wpq = array(
             'post_type' => 'document-tutorial',
               'orderby'  => 'title',
               'order'=>ASC,
               'posts_per_page'=>-1,
               'tax_query'=>
                array(
                             'taxonomy' => 'document-category',
               		'field' => 'term_taxonomy_id',
    			'terms' => array($term_tax_id),
    			'include_children' => false
    			)
               );

    That produces and empty set and the “term_relationships” part in the above query is not included in the request.

    I feel like I am missing something in the tax_query setup or some other means to show items that are only in the term I want.

    Any help would be appreciated.

Viewing 7 replies - 1 through 7 (of 7 total)
  • This is one of those solutions where you have to read between the lines in the Codex (and do a bunch of searching for similar solutions).

    Your second chunk of code is on track. What you need to do is to specifically exclude all the descendant values. Here is an extension of your example that should work:

    $args = array(
      'taxonomy'     => 'document-category',
      'orderby' => 'name',
      'order' => 'DESC'
    );
    $categories = get_categories($args);  // An array populated with the taxonomy values of 'document-category' taxononmy
    
    echo '<ul>';   // Part of testing code to display values returned by query
    
    // Loop through all the taxonomy values
    foreach ($categories as $category) {
    
      // We need to get the list of all the taxonomy value's descendants to exclude
      $termchildren = get_term_children($category->term_id, 'geography');
    
      // We want only the posts for a given taxonomy value (and exclude its children)
      $wpq = array(
             'post_type' => 'document-tutorial',
               'orderby'  => 'title',
               'order'=>ASC,
               'posts_per_page'=>-1,
               'tax_query'=>
                array('relation' => 'AND',
                  array( 'taxonomy' => 'document-category',
    			'field' => 'slug',
    			'terms' => $category->name,
    			'operator' => 'IN'
    			),
                  array( 'taxonomy' => 'document-category',
    			'field' => 'id',
    			'terms' => $termchildren,
    			'operator' => 'NOT IN'
    			)
    	      )
               );
    
      // Query to get the posts
      $parentposts = new WP_Query($wpq);
    
      // Testing Code to display the results so we can see if everything is working correctly -- replace this with your "real" loop code.
      echo '<li>The taxonomy value is: ' . $category->name ;
      echo '<ul>';
    
      while ( $parentposts->have_posts() ) : $parentposts->the_post();
        echo '<li>The post title is: ' . get_the_title() . '</li>';
      endwhile;
      echo '</ul>';
    
      echo '</li>';
    
    } // end foreach
    
    echo '</ul>';     // Part of testing code to display values returned by query

    I tested this and it works. If you have trouble post a reply with your code and the problem you are running into. I’ll try and lend a hand.

    Good luck.

    So I hope you dont mind me adding my problem with custom taxonomies. I’ve tried to find an answer and am just totally lost yet i feel like it should be fairly easy. (I have very limited knowlege of php) I built my custom taxonomy for a family blog and named the taxonomy “children” inside of that taxonomy i have made posts for each of the children in my family. (easton and kiari) I want the taxonomy to sort by post date reguardless of taxonomy. All i can get is a sort by post date for all posts in the easton taxonomy followed by all posts in the kiari taxonomy. so the question… How do i combine all the posts from my children taxonomy, and sort them to display the most recent post reguardless of weither it’s an easton post, or a kiari post?

    here’s my code i’m using to call my taxonomy now

    $tax = 'children';
    $tax_terms = get_terms( $tax );
    if ($tax_terms) {
    	foreach ($tax_terms  as $tax_term) {
    	$args = array(
    
    		"$tax" => $tax_term->slug,
    		'post_type' => 'post',
    		'post_status' => 'publish',
    		'posts_per_page' => -1,
    		'caller_get_posts'=> 1,
        	'orderby' => 'post_date',
        	'order' => 'DESC',
    
    	);
    
    		$my_query = null;
    		$my_query = new WP_Query($args);
    
    		if( $my_query->have_posts() ) : ?>
    
    		<?php while ( $my_query->have_posts() ) : $my_query->the_post(); ?>

    I think you might be over complicating things. The following code would retrieve all the posts that have a value assigned in the ‘children’ taxonomy. You can add additional arguments to the query (orderby, order) to customize the results. (I believe by default it should return the posts in reverse chronological order.)

    $args = array(
    	'tax_query' => array(
    		array(
    			'taxonomy' => 'children',
    			'field' => 'slug',
    			'terms' => get_terms('children','fields=names')
    		)
    	)
    );
    
    $my_query = new WP_Query( $args );

    definitely easier than what i was doing. Thanks a ton it worked like a charm

    Hey, maybe you could help me with another problem i’m having. I got my query to work, but now what i believe is called pagination is broken. The links to later posts shows up on the bottom, but when i click them they just reload the same set of posts as before. The page url changes to/page/2 but the posts remain the same. I’ve tried fixing it using some help i found on a few sites, but so far no luck. Here’s my code.

    $args = array(
    	'tax_query' => array(
    		array(
    			'taxonomy' => 'family-life',
    			'field' => 'slug',
    			'paged' => $paged,
    			'posts_per_page' => -1,
    			'terms' => get_terms('family-life','fields=names')
    		)
    	)
    );
    		$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    		$temp = $wp_query;
    		$my_query = null;
    		$my_query = new WP_Query($args);
    			$wp_query->query('showposts=5' . '&paged='.$paged);
    
    		if( $my_query->have_posts() ) : ?>
    
    		<?php while ( $my_query->have_posts() ) : $my_query->the_post(); ?>

    To exclude children of the requested term from queries in hierarchical taxonomies you should also try the ‘include_children’ parameter which is not mentioned on the codex but seems to work. Here’s an example:

    'tax_query' => array (
    	array(
    		'taxonomy' => 'category',
    		'field' => 'slug',
    		'terms' => 'americas',
    		'include_children' => false,
    	),
    ),

    I’m just writing this to confirm @jeremyclarke’s solution. Looks like the ‘include_children’ parameter actually works. Thanks for mentioning it!

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘Custom taxonomy query that excludes children posts’ is closed to new replies.