Showing related posts in WordPress without killing performance

Related posts are a really cool feature that can help increase pageviews on your blog. Most people don't know how to add related posts so they do the typical WordPress thing, install a crappy plugin. I can tell you that if you're using the YARPP plugin, it's only a matter of time before your database gets bloated, your site slows down, and maybe even grinds to a halt.

You don't need all the extra junk that comes with a plugin to display related posts. You just need one simple function that queries posts with the same tag(s) or category of the current post and outputs links in a list. There is no reason to be adding things to the database.

There are two functions in the embedded gist below. The first one is the jt_related_posts() function which will show related posts by category. The second one should only be used inside genesis themes, I'll talk more about it later.

The jt_related_posts() function should be placed in your functions.php file. After placing the function in functions.php you can then call the function inside your templates. Specifically you should call the function (and echo it) somewhere after the_content() in your single.php file.

The function takes 2 arguments (title and count). The arguments are optional and default to "Related Posts" for the title and 5 for the number of related posts to be displayed.

You could call it like this echo jt_related_posts(); for the default. If you wanted it to show up on something like a custom post type of "portfolio", you could call it like this inside of single-portfolio.php echo jt_related_posts('See more client sites', 3);, which would show the custom title you passed in and 3 posts.

Notice that this function will first look for posts sharing the same tag. If it doesn't find any shared tags it will show posts in the same category, if no posts share the same tag or category, no related posts will be shown.

Also notice that this function uses get_posts() which grabs an array of posts. That means there is no need to use wp_reset_postdata() or wp_reset_query(). We're not creating a new query object or customizing the main query. We're simply (and non obtrusively) grabbing an array of posts and outputting their links in an unordered list.

Now about that other function do_jt_related_posts(). That function can be used inside Genesis themes. It automatically executes the related posts function after a post using a genesis hook (genesis_after_post_content). Doing it this way means you don't have to put it inside the single.php template and allows you to add some extra logic in that can stay inside of functions.php where it belongs, not inside of a template.

It's obviously okay to call functions inside your template, but if you see a template that has a bunch of code in it handling logic then you're doing it wrong. Functions and logic should be inside functions.php. You call the functions inside of your templates. Templates are for structuring html and putting content in the right places, not for handling a bunch of logic for functions.

Why is it bad to put logic inside of templates? Multiple reasons. It makes your site harder to edit (the logic isn't in one place), it makes your templates ugly and difficult to work with. Just remember templates are for html and calling functions, not really for creating them. Besides that, a function inside of functions.php can be used in any template, so there is no need to go rewriting a function in each template.

  • http://chimaeraimaginarium.wordpress.com Richard William Posner

    First, thanks for following @ Twitter.

    I’m of course impressed with your skills and credentials, especially since what you’re into is so esoteric that I don’t really have a clue when it comes to the details. The most I’ve been able to manage is the occasional use of a little rudimentary HTML, like italic or bold and so on.

    Since I use WordPress for my “blog”, I thought I’d take a look at this particular article. I wouldn’t mind having the related posts function for my essays.

    While I’ve no doubt that the information above is very useful to those who share at least a modicum of your knowledge about the subject, technologically challenged individuals like me are basically lost with the first sentence.

    First I’d have to do some research to find out what and where my “php” file is. But then I wouldn’t be sure how much of the the code was part of the “jt_related_posts() function”.

    Then, to “call the function”, whatever that means, I’m guessing some part of this script, if that’s what this is, needs to be added to the post template. So all I’d need to do is figure out where that is and what part of the script to add to it.

    So, I guess this is why a lot of people end up using a “crappy plugin”. We haven’t devoted the time and effort that you have to learning these strange languages, so we rely upon widgets created by people who have.

    It may be because we’re too lazy or unintelligent to do the work or understand the concepts, or, it may be that we simply aren’t sufficiently intrigued or excited by the mystery of how these things work.

    All that being said, I do appreciate and admire your efforts and skill and I’m sure there are many who find the information you provide very useful.

    Anon,
    Richard
    (P.S. I don’t know about you, but I find it very helpful, when commenting, to have a “preview” function available for proofing before committing to “POST COMMENT”. Gives me a chance to avoid looking like a complete idiot in overlooking some glaring error.)

    • Justin Tallant

      This post is aimed to help people who have a basic understanding of how php and WordPress templates work. You would need FTP or SSH access to your site. If you really want to learn how to edit the code in your theme, do a google search on FTP and download an FTP client like cyberduck. As far as previewing your comments goes, if you’re so worried about it you can write them in a text editor like Sublime Text and do a spell check. To edit the code in your templates you will need a text editor. If you want to know how WordPress works in detail and want to start editing code you should check the WordPress Codex.

  • Christopher

    Hi Justin,

    Thanks so much for this. Works much better than most of the others I’ve seen and easy to understand. I’m running into one small problem in trying to add the post_date. I was trying to mirror your . $related->post_title . with . $related->post_date ., but it gives back a date like 2009-06-19 08:39:00. How would I adjust that to read as Jun. 19, 2009?

    CW

    • Justin Tallant

      You can try using the mysql2date() function. When you are using $related->post_date you are actually grabbing the date field from the database. So the mysql2date('M j Y', $related->post_date) function would be appropriate for that. You can also do something like get_the_date($related->ID). See Formatting Date and Time in the WordPress Codex for more options and details on date formatting.

      • Christopher

        Thanks! That mysql2date function worked perfectly.