1

A client of mine has custom post types that they set up using a plugin rather than defining them in the functions.php. (So, YARPP for the solution won't work). In this custom post types, they have various categories. Each post belongs to one or more categories. After each post, they would like to display 5 posts that are in ALL the same categories (could be one or many categories).

So, what I need to do is set up a way to dynamically find all the categories a post belongs to (I've done that & have it set up as an echo right now until I work this out), then query to find 5 posts that belong to the exact same categories (either they belong to all of them or they shouldn't be displayed).

Here's the code I've come up with - but, I can't figure out how to "combine them" so it not only gets the terms (categories) but also forces the query to use those terms to filter the 5 "related" programs.

  //get the post's terms (troubleshooting - can be removed once figured out!   
$category_terms = wp_get_object_terms($post->ID, 'category');
if(!empty($category_terms)){
  if(!is_wp_error( $category_terms )){
    echo 'Terms <ul>';
    foreach($category_terms as $term){
      echo '<li><a href="'.get_term_link($term->slug, 'category').'">'.$term->name.'</a></li>'; 
    }
    echo '</ul>';
  }
}  
//get post terms done
    // get the custom post type's taxonomy terms

    $custom_taxterms = wp_get_object_terms( $post->ID,
                'category', array('fields' => 'ids') );
    // arguments
    $args = array(
    'post_type' => 'program_listings',
    'post_status' => 'publish',
    'posts_per_page' => 5, // you may edit this number
    'orderby' => 'rand',
    'tax_query' => array(
        array(
            'taxonomy' => 'category',
            'field' => 'id',
            'terms' => $custom_taxterms
        )
    ),
    'post__not_in' => array ($post->ID),
    );
    $related_items = new WP_Query( $args );
    // loop over query
    if ($related_items->have_posts()) :
    echo '<h2>Other Programs in this category</h2><ul>';
    while ( $related_items->have_posts() ) : $related_items->the_post();
    ?>
        <li style="margin-left:10px;list-style:none;"><a href="<?php the_permalink(); ?>"
                   title="<?php the_title_attribute(); ?>">
            <?php the_title(); ?></a></li>
    <?php
    endwhile;
    echo '</ul>';
    endif;
    // Reset Post Data
    wp_reset_postdata();

So, get the posts terms & echo them (it won't be an echo when it's finished - I was doing that to make sure it actually got the categories/terms) works great. It displays every "category" the post is in. But, the second bit displays posts from any of those categories rather than posts that are only in ALL the categories.

Basically, I need to combine the first & second pieces so that the query only returns results of posts that are in ALL categories of the current post. If a post is not in all the same categories (exact match for ALL categories of current post), it should not be returned. (For example, if a post is in the parent "North America" category, but, not any of the other categories that the post is in, it should NOT be returned in the results).

0

2 Answers 2

1

This is the code that was needed in order to make it show only the posts (that were of a specific custom post type) that matched the same child category (therefore matching all the other categories):

<!-- other posts -->
<?php 
//this gets the lowest hierarchical child term for current post
$categories = get_the_category($post->ID);
foreach($categories as $category) :
    $children = get_categories( array ('parent' => $category->term_id ));
    $has_children = count($children);
    if ( $has_children == 0 ) {
    $current_child = $category->name;
    }
endforeach;
//this starts the query for the program listings custom post types
$post_type = 'program_listings';
$tax = 'category';
$tax_terms = wp_get_object_terms($post->ID, 'category');
if ($tax_terms == $category_terms) {
  foreach ($tax_terms  as $tax_term) {
    $args=array(
      'post_type' => $post_type,
      "$tax" => $tax_term->slug,
      'post_status' => 'publish',
      'operator' => 'AND',
      'posts_per_page' => 5,//limits the listing to 5
      'caller_get_posts'=> 1,
      'post__not_in' => array ($post->ID),
      'orderby' => 'ID', //orders by ID, you could also tell it to order by: ‘author’ ‘title’‘name’‘date’ or ‘rand’
'order' => 'ASC', //tells it the display order should be ascending, DSC would indicate a descending order

    );
    $my_query = null;
    $my_query = new WP_Query($args);
        if( $my_query->have_posts() && $tax_term->name == $current_child)//now only display categories the current post is in
         {
      echo '<h2>Other programs in this category</h2><ul>';
      while ($my_query->have_posts() && $tax_term->name==$current_child ) : $my_query->the_post(); ?>
        <li style="margin-left:15px;list-style:none;"><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></li>
        <?php
      endwhile;
    }
    wp_reset_query();
  }
}
echo '</ul>';
?>

<!-- end other posts -->
1
1

Have you tried adding an 'operator' to your tax_query:

'tax_query' => array(
    array(
        'taxonomy' => 'category',
        'field' => 'id',
        'terms' => $custom_taxterms,
        'operator' => 'AND'
    )
),
8
  • yes, I did & it returned all results (not just the custom post types if they contain all the categories). Commented Jul 31, 2013 at 0:57
  • Strange I've just tested this on a local site and it works just fine with the operator 'AND' added to the tax_query.
    – erichmond
    Commented Jul 31, 2013 at 7:57
  • it could be because the custom post types were set up with the custom post types plugin - which seems to set them up differently than doing it manually. When I added the operator, it didn't limit it to the custom post types. Commented Jul 31, 2013 at 15:20
  • Can you code the CPT and disable the plugin? Probably better to do it that way anyway.
    – erichmond
    Commented Jul 31, 2013 at 15:37
  • I can't disable the plugin - they've built the entire site around it (it's EXTREMELY extensive). That's why I'm working so hard to try to figure this out (if it was up to me, we could have coded the CPT for them). I've completely revised the code - now, I can get it to display the programs in only the related categories but NOT only programs that are in ALL the related/current categories (I've pasted it at pastebin: pastebin.com/FT0yQaEy) Commented Jul 31, 2013 at 17:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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