WordPress REST API: Pull Through Posts From Another WordPress Site

I recently needed to pull through 2 or 3 posts (they were recipes in this instance) from another WordPress website into the current WordPress project I was working on. It seemed tricky at first and then I remembered the WordPress Rest API!

As of version 4.7, the REST API is included out of the box and plugins are no longer required. The endpoints are accessible to anyone by appending /wp-json/wp/v2/posts to the end of the website’s URL (provided they are using WordPress 4.7 and higher)

Thankfully, with the help of a little snippet of code I wrote (see below), that was more than enough to get random posts pulling through from another WordPress website along with a like to that post and it’s featured image.

Update 09 July 2018: I’ve improved the code below. Simply throw the below into your functions.php file:

/**
 * Add this to your functions.php file
 * Using the REST API, retrieve posts from another website.
 * Retrieves images and renders the output below called via a [render_recipes] shortcode
 */
function get_recipes()
{
    // Enter The URL to the API here:
    $api_url = 'https://www.website-goes-here.com/wp-json/wp/v2';

    // Retrieve 100 items via the WordPress RestAPI - can be increased
    $response = wp_remote_get(add_query_arg(array(
        'per_page' => 100
    ), $api_url . '/recipes'));

    // Make sure the response is valid before we proceed...
    if (!is_wp_error($response) && $response['response']['code'] == 200) {
        $remote_posts = json_decode($response['body']); // Our posts are stored here

        uksort($remote_posts, function() { return rand() > rand(); }); // Shuffles the results around

        $remote_posts = array_slice($remote_posts, 0, 2); // Limits the array to 2 items for render

        // Loop through each item and render it
        foreach ($remote_posts as $remote_post) {
            echo '<div class="recipe-post col-md-6">
			    <a href="' . $remote_post->link . '" target="_blank" rel="noopener">';

            // Lets go get the corresponding media for each item looped, on the fly
            $medias = json_decode(file_get_contents($api_url . '/media/'. $remote_post->featured_media));

            // Render the image
            echo '<img class="nwc-recipe-img" src="' . $medias->source_url . '" alt="' . $remote_post->title->rendered . '">';

            // Render the title
            echo '<h5 class="nwc-recipe-title">'. $remote_post->title->rendered . '</h5>';

            echo '</a>
            </div>';
        }
    }
}

// Add the [render_recipes] shortcode
add_shortcode('render_recipes', 'get_recipes');

Then, you can call the function via a shortcode on your .php theme pages like so:

<?php
 // Add this to the .php page you need to call it on.
 do_shortcode('[render_recipes]');
?>

Quick break down of how the above function works:

  1. Retrieves the posts list in JSON format from the site’s WordPress Rest API
  2. If the response is a valid one, decode the posts and start looping through the results
  3. Retrieves 100 posts, shuffles it around and then sets a limit to 2 (all I needed in this example).
  4. Chuck the responses in a basic div element (div called recipe-post in this case, but also has a bootstrap class of col-md-6)
  5. While looping through each item, also get the media attached to that post. $remote_post->featured_media returns an id in this instance.
  6. We then spit out the $medias source_url (the full path to the full featured post image)
  7. Then spit out the title and close up the <div>

The above works fairly well in my instance I needed it for. Hopefully, the above snippet of code comes in handy for you too.

Some things to keep in mind using the above:

  • This may potentially slow down your site as it has to make a few more calls. (Set the per_page argument lower if it’s taking too long)
  • This will only work on websites using WordPress 4.7 and higher (relies on the REST API natively added in this version )
  • This also assumes the default endpoints are enabled and not blocked or closed up.

Leave a comment