WordPress Related Posts by Category Function

This function finds posts from the same categories as the current post, and returns an HTML list. Use it in single.php, or inside a filter on the_content.

function tc_related_posts( $post_id = null, $limit = 3 ) {
	$post_id = $post_id ? $post_id : get_the_ID();
	$cats    = wp_get_post_categories( $post_id );

	if ( empty( $cats ) ) {
		return '';
	}

	$query = new WP_Query( array(
		'category__in'           => $cats,
		'post__not_in'           => array( $post_id ),
		'posts_per_page'         => $limit,
		'ignore_sticky_posts'    => true,
		'no_found_rows'          => true,   // faster: we do not need pagination
	) );

	if ( ! $query->have_posts() ) {
		return '';
	}

	$html = '<ul class="related-posts">';
	while ( $query->have_posts() ) {
		$query->the_post();
		$html .= '<li><a href="' . esc_url( get_permalink() ) . '">' . esc_html( get_the_title() ) . '</a></li>';
	}
	wp_reset_postdata();

	return $html . '</ul>';
}

Test it

We create two categories and four posts, and ask for the related posts of the first one:

function tc_related_posts( $post_id = null, $limit = 3 ) {
	$post_id = $post_id ? $post_id : get_the_ID();
	$cats    = wp_get_post_categories( $post_id );
	if ( empty( $cats ) ) {
		return '';
	}
	$query = new WP_Query( array(
		'category__in'        => $cats,
		'post__not_in'        => array( $post_id ),
		'posts_per_page'      => $limit,
		'ignore_sticky_posts' => true,
		'no_found_rows'       => true,
	) );
	if ( ! $query->have_posts() ) {
		return '';
	}
	$html = '<ul class="related-posts">';
	while ( $query->have_posts() ) {
		$query->the_post();
		$html .= '<li><a href="' . esc_url( get_permalink() ) . '">' . esc_html( get_the_title() ) . '</a></li>';
	}
	wp_reset_postdata();
	return $html . '</ul>';
}

echo "Related to post 5 (Learn hooks):\n" . tc_related_posts( 5, 3 ) . "\n\n";
echo "Related to post 8 (Site news, only post in News): [" . tc_related_posts( 8, 3 ) . ']';
Output

Related to post 5 (Learn hooks):
<ul class="related-posts"><li><a href="http://example.com/learn-the-loop/">Learn the Loop</a></li><li><a href="http://example.com/learn-wp_query/">Learn WP_Query</a></li></ul>

Related to post 8 (Site news, only post in News): []

The post itself is not in its own list, and a post with no other post in its category gets an empty string. Print the result in your template with echo tc_related_posts();.


Learn more about the similar topics:
Tutorials
No Content Found.
Exercises & Assignments
No Content Found.
Interview Questions & Answers
No Content Found.