I'm creating a "Related posts" section for my theme, based on a tutorial from wpbeginner.com. It offered two options in selecting posts: those in the same category(ies), using category__in, or those with the same tag(s), using tag__in.

Is it possible to put of them into one big mixing pot, if you will, and select posts from all of them? I don't mean those that have the same category(ies) AND the same tag(s), but those that have either or.


Yes, that is possible. All Taxonomies are stored in the db in the wp_term_taxonomy table. The following are all listed as taxonomies

  • category

  • post_tag

  • link_category

  • post_format and

  • Custom taxonomies

All terms belonging to these taxonomies are stored in the wp_terms table. Tags are terms of the post_tag taxonomy, and all "categories" that you create in the post menu screen under "Categories" are actually terms of the taxonomy category

This makes it easy to combine the different taxonomies and terms in one query. To accomplish this, you are going to make use of the Taxonomy Parameters in WP_Query to run a custom tax_query

OK, so first we need to get a list of all the categories and tags that belongs to a post. For categories you are going to use get_the_category and for tags get_the_tags. You are going to return that as an array which you are going to use in your custom query

global $post;
//get the categories a post belongs to          
$cats = get_the_category($post->ID);

$cat_array = array();
    foreach($cats as $key1 => $cat) {
        $cat_array[$key1] = $cat->slug;

//get the categories a post belongs to      
$tags = get_the_tags($post->ID);

$tag_array = array();
    foreach($tags as $key2 => $tag) {
        $tag_array[$key2] = $tag->slug;

Here is your custom query arguments. You can go and have look at the taxonomy parameters in the link to WP_query I've supplied. Also go and look at all the parameters that you can use in WP_query as some parameters from that tutorial have been depreciated a long time ago, for instance, like caller_get_posts which was replaced with ignore_sticky_posts

$args = array(
    'posts_per_page' => 5,
    'orderby' => 'rand',
    'tax_query' => array(
        'relation' => 'OR',
            'taxonomy' => 'category',
            'field' => 'slug',
            'terms' => $cat_array,
            'include_children' => false 
            'taxonomy' => 'post_tag',
            'field' => 'slug',
            'terms' => $tag_array,

$the_query = new WP_Query( $args );

You can go play around with the code and modify as you wish.

| improve this answer | |
  • Thank you. It works like an absolute dream. It will probably work better once I've styled everything, but that is exactly what I was looking for. – Nate Jul 27 '14 at 17:22
  • I'm glad I could help. Enjoy :-) – Pieter Goosen Jul 27 '14 at 17:29
  • @Laxmana My pleasure. Glad my answer was useful to you as well :-) – Pieter Goosen Jul 31 '14 at 4:21
  $arrCats = array();
  $arrTags = array();

  if ($cats = get_the_category($post->ID)) foreach ($cats as $cat) $arrCats[] = $cat->term_id;
  if ($tags = wp_get_post_tags($post->ID)) foreach ($tags as $tag) $arrTags[] = $tag->term_id;

  $args = array(
    'numberposts'     => $num,
    'category__in'    => $arrCats,
    'tag__in'         => $arrTags,
    'post__not_in'    => array($post->ID),
    'orderby'         => 'post_date',
    'order'           => 'DESC',
    'post_type'       => $post->post_type,
    'post_status'     => 'publish'

  $posts = get_posts( $args ); 
| improve this answer | |
  • 1
    It might be a good idea to explain why and how this will solve the OP's problem, rather than posting only code. – Johannes Pille Jul 28 '14 at 12:09

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.