Fetch and display remote posts via WordPress REST API

In this article we’ll take a look at how we can fetch some posts from a remote WordPress blog and display them on another WordPress site. For example, you might have two different WordPress websites and write about different topics. But, some topics may be of interest to the readers of both of your blogs. In this case, you might want to offer your readers some posts from the original blog.

Now, I don’t encourage you to duplicate posts from the original to another blog (SEO reasons), but you might want to offer a feed of articles from the original blog, and link them back to the original blog from the second one. And this is exactly what I’ll show you how to do. We’ll create a page template with the feed of articles that will display things like image, title and description, and a link to the original post.

What you’ll need:

  1. Working REST endpoint for ‘posts’ on the original website
  2. A blank page template on the second blog where we’ll embed the posts feed

So, let’s get started.

Page template for displaying the feed

First, we’ll create a blank page template and give it a name. Create a file inside the root of your WordPress theme. We’ll call it ‘template-page-feed.php‘. Inside the file, you’ll put this code at the very top:


    /**
 * Template Name:Posts Feed
 */

This is the standard way to initialize a blank page template in WordPress and make it available in the template selector inside the page edit screen in WordPress dashboard. So, go ahead and create a new page and set the active template to our new Posts Feed template. If you need some more information on the topic of WordPress page templates, there’s a wealth of information in the official Page Templates article on wordpress.org.

Anyway, after we’ve created our blank page template, it’s time to write some code. Yay!

Some consideration before accessing any REST API

Now, when fetching remote data from a REST API, there’s some performance consideration to take into account. Since we’re displaying our feed when a visitor loads the page, what we don’t want to do, is to make a remote API request on each page load. This would unnecessarily put extra load and could lead to some undesirable behavior on the remote server. Also, in general, many API’s have a rate-limit where you can only make a certain amount of requests before you get locked out (or even billed heftily), so it’s never a good idea to put yourself into a situation where you’re making an unpredictable amount of external API requests.

This is why we’re going to cache our API response.

WordPress transients

A handy way to cache things in WordPress is to use transients. Transients are temporary data stored in a WordPress database that have an expiration date. Now, transients can be deleted automatically even before the expiration date (perhaps through a database maintenance or a similar action), but transient data will never exist after an expiration date. But that should not matter – transients are absolutely not a way to store any critical data, but only the data that can easily and automatically be created over and over again. And this is a perfect solution for our REST API data because it will save us many API calls to our remote site.

So, the first thing we’ll do, before writing our API call, is to check whether we already have a data in our transient. It looks a little bit like this:


    /**
 * Template Name:Posts Feed
 */

define( 'HOURS', 60 * 60 * 12 );
function get_remote_api_data( ) {
 global $apiData; 
    if( empty($apiData) ) $apiInfo = get_transient('api_data'); 
    if( !empty($apiData) ) return $apiData;
}

So, let’s go through this code line by line:

  1. Line 5 – we’re defining our ‘HOURS’ constant that we’ll use for the expiration time for our transient. In this case, I’ve set it to 12 hours (in seconds). We’ll need this later on in our code.
  2. Line 7 – the name of our function. I find it easier to define a function and then call it later on when and where I need it.
  3. Line 8 – 9 – we’re checking whether we have any data in our variable. If we don’t’, we’ll fetch our transient entry named ‘api_data’ (line 8). If we do, we’ll simply output it(line 9).

So, the first part revolves around checking if we already have any API data at all, or if we have any API data in our transient. But, what if we don’t? We then make the magic that is called remote API request.

Remote API request

By now we’ve determined we have no previous data in our variable or our transient, and we’re ready to make the call. This is how it’s done:


      $response = wp_remote_get('https://codeart.studio/wp-json/wp/v2/posts?per_page=5&_embed',  array(
      'timeout'     => 20,
  ));
    $data = wp_remote_retrieve_body($response);
    
if( empty($data) ) return false;

    $apiData= json_decode($data);
   
    set_transient( 'api_data', $apiData, HOURS ); 

    return $apiInfo;

Let’s take a look what’s going on in the above code:

  1. Line 1 – 3 – this is where the magic happens, and it’s quite simple. We’re making a call to our ‘posts’ endpoint by using wp_remote_get function, and we’re setting the timeout for the call to 20 seconds. I’ve found that this is (for me at least) a sweet spot for how much I’m willing to wait for the call to complete. Anything more than that and something’s wrong, and anything less than that and you might not finish what you started in the first place. We’re appending two parameters to the call – the ‘posts_per_page’ (a standard wp_query argument for retrieving an X amount of posts), and ‘_embed’, which gives us all the necessary data attached to a single post without the need to request more data (most notably the URLs to the featured images).
  2. Line 4 – by using wp_remote_retrieve_body we’re parsing our data so that we’re only left with the body of the response, because that’s really all we need.
  3. Line 6 – if there’s no response, we stop the execution of our function.
  4. Line 8 – since the data we’ve received is in the JSON format, we need to convert it into a PHP array so that we can use it to render our post later on, therefore we use json_decode.
  5. Line 10 – this is where transients and caching come into play. Like I wrote earlier, in order to reduce the number of remote API request, we’re storing our response inside a transient entry called ‘api_data’, and setting it to expire in 12 hours (or any number of days / hours / minutes / seconds you might want). For the expiration time we use the constant we’ve defined earlier, ‘HOURS’.
  6. Line 12 – last but not least, we return the result of our function.

So, let’s put together the entire function once more inside a single code block:


    define( 'HOURS', 60 * 60 * 12 );
function get_remote_api_data( ) {
 global $apiData; 
    if( empty($apiData) ) $apiInfo = get_transient('api_data'); 
    if( !empty($apiData) ) return $apiData;

  $response = wp_remote_get('https://codeart.studio/wp-json/wp/v2/posts?per_page=5&_embed',  array(
      'timeout'     => 20,
  ));
    $data = wp_remote_retrieve_body($response);
    
if( empty($data) ) return false;

    $apiData= json_decode($data);
   
    set_transient( 'api_data', $apiData, HOURS ); 

    return $apiInfo;

}

So, now that we have a ready function for making the remote API call, we need to use it, and render our posts.

Rendering the posts from the remote API data

Let’s get our data by using our function and store the data into variables before we render it:


    $feed = get_remote_api_data();
if($feed) : 
foreach($feed as $post) {
    $title= $post->title->rendered;
    $image= $post->_embedded->{'wp:featuredmedia'}[0]->media_details->sizes->{'medium'}->source_url;
    $excerpt= $post->excerpt->rendered;
    $link = $post->link;

Let’s see what we’re doing in the above code block:

  1. Line 1 – we’re getting the data from our function
  2. Line 3 – We loop through our data to get the information for each post
  3. Line 4 – 7 – we’re getting the post data, the title, featured image, excerpt and link (back to our original website of course) and storing it into variables.

A note on the Line 5 – by using the _embedded key, we’re fetching the linked resource, in this case the media for the post, and getting the information we need to create a link to the media (the size and the URL of that image size).

Rendering the posts

Now that we have all the data we need, we’re rendering the post (remember, we’re still inside the foreach loop):


    foreach($feed as $post) {
    $title= $post->title->rendered;
    $image= $post->_embedded->{'wp:featuredmedia'}[0]->media_details->sizes->{'medium'}->source_url;
    $excerpt= $post->excerpt->rendered;
    $link = $post->link;

    $html = '<div class="featuredImage"><a href="'.$link.'"><img src="'.$image.'" /></a></div>'; //the image and the link
    $html .= '<div class="title"><h3><a href="'.$link.'">'.$title.'</a></div></h3>'; //the title and the link
    $html .= '<div class="excerpt">'.$excerpt.'</div>'; //the excerpt

    echo $html;
} //end foreach loop

And, that’s pretty much it. Now you have a loop of posts displayed from a remote website via WordPress REST API. Isn’t that cool?

Hire your codeartist

looking for a development of your own project?

is your agency looking for a partner?