WordPress: Related posts with WP_Query.
Tags: wordpress, webdev, php, css
Published: 2020-04-15 17:40:34

---
title: WordPress: Related posts with WP_Query.
published: true
description: A tutorial about working with the WordPress WP_Query class to create a related post template part for your theme with php
canonical_url: https://since1979.dev/wordpress-related-posts-with-wp_query/
cover_image: https://since1979.dev/wp-content/uploads/2020/04/wordpress-relate-posts-with-wp_query.jpg
tags: wordpress, webdev, php, css
---
[Originally posted on my website on April 15th 2020](https://since1979.dev/wordpress-related-posts-with-wp_query/)

### Creating a related posts template part with WP_Query.

In this article I'd like to show you how you can make a "related articles" section like the one i have below the articles on [my own website.](https://since1979.dev/)

On my website I have categorized articles into three categories: [Tutorials](https://since1979.dev/wordpress-development-tutorials/), [Snippets](https://since1979.dev/wordpress-development-code-snippets/), and [Digest](https://since1979.dev/wordpress-development-monthly-digest/) articles. I use the build in category feature of WordPress to assign articles to their corresponding category. Below each single post I display the three latest posts from the same category, or categories, as the post itself excluding the post displayed on the page itself.

To filter these posts I use WordPress's *WP_Query* class. This class offers many many arguments that you can mix and match to get just the posts you need. I highly recommend you take the time and read through [the docs](https://developer.wordpress.org/reference/classes/wp_query/) because the *WP_Query* class is a very powerful tool to have in your tool belt.

With that said, let's build our own related posts template part.

### The template part

To start of our new section we need to create a new template part file called relatedposts.php. I created it in a folder called "parts" but you can place it anywhere you like. We then need to include it in our *single.php* template file. For this we can use the *[get_template_part](https://developer.wordpress.org/reference/functions/get_template_part/)* function and call it somewhere below our main content section with the snippet below.

{% gist https://gist.github.com/vanaf1979/1dc8dfdf3c3c2785573e74e52fc57c98 %}

The *get_template_part* function takes a single string argument being the path to our template part file relative to our theme's folder, and without the .php extension

### Html markup

With our template part file included we can start adding the Html markup. Copy the markup below into our relatedposts.php file.

{% gist https://gist.github.com/vanaf1979/700e3156c1961bd1fba6a4c900c3e0a1 %}

This markup adds a wrapper div with three "item" div's each containing a linked [placeholder image](https://placeholder.com/) and a linked H5 posts title.

### Adding some style

To make our related posts look somewhat presentable we can add the Css styles below.

{% gist https://gist.github.com/vanaf1979/336ac3d7c912dca8b873908eae8cc7f8 %}

The above Css creates a three collumn [Css grid layout](https://www.w3schools.com/css/css_grid.asp) with 40px gutters. It also makes the images responsive and adds some margins. Resulting in a layout like shown in the image below.

![](https://since1979.dev/wp-content/uploads/2020/04/wordpress-related-posts-wp-query-html.jpg)

### Fetching posts with WP_Query

Now we want to get the three latest posts from the same categories as the current post, excluding the current post itself. For this task we can use the *WP_Query* class. With the *WP_Query* class we can query the database for posts based on a list of requirements like shown in the code below.

{% gist https://gist.github.com/vanaf1979/df67acc72406a26726b03404835c44a2 %}

Here we create a new instance of the *WP_Query* class and pass it a single argument being an array with the following parameters:

-   **post_type:** The post type we want to select. In our case we want posts, so we pass post.
-   **category__in:** A list of categories the posts can belong to. Here we use the *[wp_get_post_categories](https://developer.wordpress.org/reference/functions/wp_get_post_categories/)* function combined with the *[get_the_ID](https://developer.wordpress.org/reference/functions/get_the_id/)* function to get an array of categories assigned to the current post. This will get us posts that are in the same categories as the current post.
-   **post__not__in:** An array of posts to exclude from the results. In our case we pass an array with the ID of the current post.
-   **posts_per_page:** The number of posts to return. In our case we need three posts so we pass a 3.
-   **orderby:** How to order the posts. We want the latest posts so we pass date.

This call to the *WP_Query* class should give us a instance of this class stored in a variable called *$related_query*. This instance includes the post we want. Now we just need to show them on the page.

### Loop through the posts

To show the results from our query we need to set up a custom loop. This loop is pretty similar to a standard [WordPress loop](https://developer.wordpress.org/themes/basics/the-loop/). But instead of calling template tags we have to call these functions as [class methods](https://tutorials.supunkavinda.blog/php/oop-methods) on our new *$related_query* instance. E.g. *have_posts()* will become *$related_query->have_posts()*.

First let's initialize the loop like shown below.

{% gist https://gist.github.com/vanaf1979/7f13d99ce33fb39f9901241e306d06f2 %}

Here we first check if our query has found any posts by using the *[have_posts](https://developer.wordpress.org/reference/classes/wp_query/have_posts/)* method. If so, we open our grid container div and start the loop with a while loop with the same *have_posts* method.

Inside the loop we use the *[the_post](https://developer.wordpress.org/reference/classes/wp_query/the_post/)* method to set up the post data. This sets the *$post* global to the current post in the loop so we can use the standard template tags.

After our loop we use the *[wp_reset_postdata](https://developer.wordpress.org/reference/functions/wp_reset_postdata/)* function. This function restores the *$post* global to the current post in the main query.

Now let's output our post data inside the loop.

{% gist https://gist.github.com/vanaf1979/5c3ec8b4b55e33ce3c76ef85060cc105 %}

With each iteration of the loop we add a div with a *grid-item* class. Inside this div we use the *[the_permalink](https://developer.wordpress.org/reference/functions/the_permalink/)* and *[the_post_thumbnail](https://developer.wordpress.org/reference/functions/the_post_thumbnail/)* functions to add the posts featured image with a link to the post.

Then we use the *[the_permalink](https://developer.wordpress.org/reference/functions/the_permalink/)* and *[the_title](https://developer.wordpress.org/reference/functions/the_title/)* functions to add a linked H5 element with the posts title.

All this should give us a output like shown in the image below.

![](https://since1979.dev/wp-content/uploads/2020/04/wordpress-related-posts-wp-query-php.jpg)

### Completed code

Below you'll find the completed code for this article so you can adapt it for use in your own theme.

{% gist https://gist.github.com/vanaf1979/87f16ea87a34eca1a38e8ca9dba82952 %}

As you can see the *WP_Query* class is a very powerful tool. and again I would recommend you read up on [its documentation](https://developer.wordpress.org/reference/classes/wp_query/) to save yourself some headaches and [stack-overflow](https://stackoverflow.com/questions/tagged/wordpress) questions in the future.

### Follow?

Follow me on twitter [@Vanaf1979](https://twitter.com/Vanaf1979) or here on Dev.to [@Vanaf1979](https://dev.to/vanaf1979) to be notified about new articles, and other WordPress development related resources.

**Thanks for reading and stay safe.**