Related Posts Without A Plugin V2

How to Add Related Posts without a Plugin

Adrienne Boswell

Having related posts on your pages is a good idea because it helps keep visitors on your site. JetPack from Automattic has that feature built-in. There are also quite a few plugins that will do this for you. The problem with JetPack and other plugins is that they are resource-intensive and can slow your site down considerably. Wouldn’t it be great if you could put related posts without a plugin? Well, you can, and I will show you how to do it.

First, I have to give credit where credit is due. I found some of this code at WP-Beginner and cleaned it up a little to use on my own site, The Good Plate. They recommend using WP-Code instead of editing your core theme files. To do this correctly, however, you must upgrade WP-Code. If you have a lot of code and need WP-Code’s upgrade features, feel free to use it instead. However, my code does not require WP-Code or any other plugin. All it requires is to know HTML markup, a little CSS, and some basic PHP.

WP-Beginner uses the default WordPress theme, but I use GeneratePress. I have adapted the code to work for Generate Press. The page you want to edit is single.php.

Create a Child Theme First

If you are not already using a child theme, I highly recommend doing so. When your theme is updated, your changes will be overwritten. A child theme prevents that from happening. If you are comfortable, WordPress has instructions on creating a child theme, or you can get a free plugin like Catch’s Generate Child Theme. Once your child theme is in place, put a copy of single.php in the child theme’s folder.

Back up, Back up, Back up!

Before doing this, make a backup of your page via FTP to your hard drive or cloud storage. Trust me! If your code contains an error, a backup must be available immediately.

Use a Text Editor

Ok, so how do you do the edit? This is not necessarily something that you would want to do online via WordPress. You also should not try to edit using MS Word or other word processors. The main reason I recommend not doing this online is because of spell checkers. Spell checkers know very little about HTML, CSS, or PHP and might “correct” the code themselves before you even have a chance to stop them. Any plain text editor, even Notepad, can be used. Of course, if you have an editor with syntax highlighting, that’s even better.

The Code

This is what the Generate Press single.php page looks like before the code is inserted. Look for the comment “generate_after_main_content_hook,” and insert the code before that comment.

 * The Template for displaying all single posts.
 * @package GeneratePress

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.

get_header(); ?>

	<div <?php generate_do_attr( 'content' ); ?>>
		<main <?php generate_do_attr( 'main' ); ?>>
			 * generate_before_main_content hook.
			 * @since 0.1
			do_action( 'generate_before_main_content' );

			if ( generate_has_default_loop() ) {
				while ( have_posts() ) :


					generate_do_template_part( 'single' );


//This is where you are going to put the code

			 * generate_after_main_content hook.
			 * @since 0.1
			do_action( 'generate_after_main_content' );

	 * generate_after_primary_content_area hook.
	 * @since 2.0
	do_action( 'generate_after_primary_content_area' );



Before you start, there are a few things that you should be aware of. I am using table markup. WP Beginner uses list markup. I prefer table markup because it can be consistently styled, whereas list markup is sometimes “hopes and prayers.” The specific markup is <div class=”relatedthumb”>. This is where the thumbnail goes if you are going to use one. You can control the thumbnail’s appearance via Appearance -> Customize -> Additional CSS.

This is the code to insert:

$orig_post = $post;
global $post;
$categories = get_the_category($post->ID);
if ($categories) {
$category_ids = array();
foreach($categories as $individual_category) $category_ids[] = $individual_category->term_id;
'category__in' => $category_ids,
'post__not_in' => array($post->ID),
'posts_per_page'=> 3, // Number of related posts that will be shown.
$my_query = new wp_query( $args );
if( $my_query->have_posts() ) {
echo '<div id="related_posts"><h3>You Might Also Like</h3>  
while( $my_query->have_posts() ) {
<td valign="top"><div class="relatedthumb"><a href="<?php the_permalink()?>" rel="bookmark" title="<?php the_title(); ?>"><?php the_post_thumbnail(); ?></a></div>
<div class="relatedcontent">
<h3><a href="<?php the_permalink()?>" rel="bookmark" title="<?php the_title(); ?>"><?php the_title(); ?></a></h3>
<?php }
echo '</tr></table></div>';
$post = $orig_post;

Feel free to change the wording. I put “You Might Also Like,” but you could put “Related Posts” or whatever verbiage you want to use.

You can change the number of related posts displayed. Three is a good number when the images are 200 pixels wide. I am using Related Posts with WP Recipe Maker, where the recipe card is 600 pixels wide. Your theme and post configuration may vary.


This is the CSS for Customizer:

#related_posts {border:0px solid blue;}
#related_posts td {
  border:0px solid green;
	display: inline-block;
  margin-right: 10px; 
	max-width: 200px;
.relatedthumb img {width:200px!important; text-align:center;}
.relatedcontent h3 {font-size:.8em; font-style:normal; text-align:center; max-width:200px; overflow: hidden;
  text-overflow: ellipsis;}
#related_posts table {border:none; border-collapse:collapse;}

You can change the width of the featured image to whatever size you want. I recommend a small size that is suitable for both desktop and mobile use.

Final Result

And this is what the Related Posts markup looks like:

Related Posts sample on desktop

This is what Related Posts look like on Mobile.

Image 1
Related Posts on Mobile

About the author

Adrienne has been a web developer for over 20 years and enjoys sharing snippets of code she has written.

Leave a Comment