How to display related posts without a plugin

"Related posts" section contains an automated selection of posts related to the article you are currently reading, and it's one of the best possible additions to your website. The multiple advantages of such a section make it a must-have:

You probably noticed the “Related articles” section on WPCrumbs. If not, scroll down to the end of the article, and just below the social media sharing buttons you will see a section like this:

Related articles section

Benefits

It contains an automated selection of posts related to the article you are currently reading, and it’s one of the best possible additions to your website. The multiple advantages of such a section make it a must-have:

  1. It improves user experience: it’s a convenient and non-intrusive way for your readers to find relevant articles based on their interests
  2. It helps with SEO: search engine optimization is a key factor that can make or break the visibility of your website in SERPs (search engine results pages). An important part of the good SEO practice is internal linking, and a “Related articles” section does just that automatically and efficiently.
  3. Lowers bounce rate: the lower the bounce rate, the better. Interested readers don’t leave your website, so keep your visitors interested by showing them relevant content.

While the section is fully automated, it will always display highly relevant, targeted posts. If a post doesn’t have any related content on your website, the “related articles” section will not be displayed (for example if your website contains articles about WordPress, writing a post with noodle soup recipes will not have any related articles to be displayed).

Adding the section in your theme

You can add the related posts section in your theme in two easy steps:

1. Add this code to functions.php
(NOTE: if you are using a child theme, add the code to the child theme’s functions.php file)

/**
 * Related posts
 * 
 * @global object $post
 * @param array $args
 * @return
 */
function wcr_related_posts($args = array()) {
    global $post;

    // default args
    $args = wp_parse_args($args, array(
        'post_id' => !empty($post) ? $post->ID : '',
        'taxonomy' => 'category',
        'limit' => 3,
        'post_type' => !empty($post) ? $post->post_type : 'post',
        'orderby' => 'date',
        'order' => 'DESC'
    ));

    // check taxonomy
    if (!taxonomy_exists($args['taxonomy'])) {
        return;
    }

    // post taxonomies
    $taxonomies = wp_get_post_terms($args['post_id'], $args['taxonomy'], array('fields' => 'ids'));

    if (empty($taxonomies)) {
        return;
    }

    // query
    $related_posts = get_posts(array(
        'post__not_in' => (array) $args['post_id'],
        'post_type' => $args['post_type'],
        'tax_query' => array(
            array(
                'taxonomy' => $args['taxonomy'],
                'field' => 'term_id',
                'terms' => $taxonomies
            ),
        ),
        'posts_per_page' => $args['limit'],
        'orderby' => $args['orderby'],
        'order' => $args['order']
    ));

    include( locate_template('related-posts-template.php', false, false) );

    wp_reset_postdata();
}

2. Create a file named related-posts-template.php with the following content:


    

[panel type="info"]Don't forget to replace wpcrumbs with your theme's textdomain in _e('Related articles', 'wpcrumbs');[/panel]

If the textdomain is not changed, the text 'Related articles' will not be translatable. Of course, you can replace 'Related articles' with 'Related posts' or any other text of your choice.

Related posts in custom post types

This function can also be used for custom post types, but you will have to register (and use) custom taxonomies for those custom post types. That's because without custom taxonomies there's no link between the posts.

Use cases and examples

[panel type="info"]Call the wcr_related_posts() function in single.php, page.php or any other file where you want to display the related posts.[/panel]

The function is very flexible and has a lot of possible arguments, so you can customize among other things the number of items displayed, the orderby criteria, the taxonomy (if you have custom taxonomies) and so on. We've included below a few examples.

Example 1 - display 3 related posts (simply call the function in the desired file)

NOTE: The default criteria on which the posts are chosen is post category

If you want to display more items, change the orderby criteria, or display related posts for a specific post ID, just add arguments to the function:


Example 2 - display 6 related posts based on post tags

 'post_tag',
   'limit' => 6
));
?>

Example 3 - display 10 related posts based on post categories (or any other taxonomy, if you have custom taxonomies), but ordered by comment_count (ASC)
See other orderby alternatives in the WordPress Codex

 10,
   'orderby' => 'comment_count',
   'order' => 'ASC'
));
?>

Example 4 - display 6 related posts for a defined post ID (eg. post with ID = 145) based on post tags

 6,
   'taxonomy' => 'post_tag',
   'post_id' => 145
));
?>

13 Comments

  1. Hi, thanks for this, just what I was searching.
    I just have a problem, when I try to get the posts by tag. I don’t get any error, I just don’t get any content.

    • Hello @Alejandro,

      Oops, my bad… tag’s taxonomy name is post_tag. Please try again with the updated code.

      Thanks.

  2. Great! thanks @George,

    One more question is there a way to include posts by category and tag together?

    Thanks again! Awesome post!

  3. Hello,
    I’m a beginner in WorldPress.
    I’d like to show Related Posts.
    In the main menu I have Category A, and in Category A – Subcategories A, B and C. The posts are in Category A, but they can also be present in all 3 Subcategories.
    When choosing one of the Related Posts something goes wrong and the posts from the initially chosen Subcategory don’t show correct anymore.

    • .related-posts {
      background:#fff;
      box-shadow:0 1px 4px hsla(20,1%,57%,.1),inset 0 -1px 0 hsla(20,1%,57%,.35),0 0 0 transparent,0 0 0 transparent;
      padding:0px 0 30px 0px;
      margin-bottom:30px;
      border-radius:3px
      }
      .related-posts-list {
      list-style-type:none;
      margin:0;
      padding:0;
      width:100%
      }
      .related-posts-list li {
      display:inline-block;
      width:33.33333%;
      margin:0;
      float:left;
      padding-right:30px
      }
      .related-posts-list li h4 {
      font-size:16px;
      color:#353535
      }

Leave a Reply

Your email address will not be published. Required fields are marked *