Display Posts with WP REST API

Display WordPress Posts on Another Site with WP REST API

API, Data, Design, Tech Tips Comments (30)

Overview

Have a WordPress site and want to include your posts on an external site? In this tutorial, I will show you how to use the WordPress REST API to display your posts on a static site with just HTML, CSS, and Javascript.

There are several scenarios where this might be useful but here are the two directly applicable to this tutorial:

  • You want to display a feed of posts on static web hosting (e.g., GitHub Pages, AWS S3, etc.) for your professional web presence
  • You want to use posts from a particular author, category, or tag for separate site(s)
    Skill Level: Beginner

Getting Started

Update 3/31/17: If you are using WP 4.7 or above you can skip to step 3. The WP REST API is now part of core. No need for a plugin.

  1. Login to your WordPress site and add the WP REST API V2 plugin
  2. Activate the plugin
    Activate WP REST API Plugin
  3. Find your route and define any endpoints. For our purposes, we’re going to retrieve all posts so we will use
    http://example.com/wp-json/wp/v2/posts/

    For example, to get all posts for this site, I will use

    http://digitalborn.org/wp-json/wp/v2/posts

    Go ahead and copy and paste that URL into your browser. You’ll get a bunch of JSON data. That’s exactly what we want.

    Note that you can narrow down your results by adding to the route. Quick terminology refresher:

    Base path of API: http://example.com/wp-json/
    Route: wp/v2/posts

    For example, we can grab just one post with the ID 2985 like this

    http://digitalborn.org/wp-json/wp-v2/posts/2985

    Or, if we want to get posts with tag ID 139

    http://digitalborn.org/wp-json/wp/v2/posts?tags=139

    For the full reference you can see the WP REST API documentation for posts

  4. Test the route in your browser. If you get post data, then we can move to the next step.Note: Only public posts will display. You can also display private posts but this is more complex and we won’t deal with private posts in this tutorial.

Get the Sample Files

I’ve added some files to get you started that allow you to simply paste the route you identified above and display posts.

  1. Clone or download the tutorial files located herehttps://github.com/nathanegraham/wp-rest-api-post-getter

    For those using the GitHub client you will click Open in Desktop. For those who do not use GitHub, just click Download Zip and then extract/unzip the filesGitHub repo download

  2. Open script.js in your favorite editor (Brackets is pretty great)
  3. In Line 2, change the route to the one you identified in the Getting Started section above
  4. Hit Save
  5. Now open index.html in your browser

Putting It All Together

Now that you have your JSON post data and you have the files to display this data on a webpage, you can add it to your site.

  1. Upload the Javascript files to your site’s directory.
    If you don’t have static web hosting I would recommend using AWS S3 or GitHub Pages. Both are free and easy to set up. I won’t go into the details but you can find instructions for AWS S3 site hosting here and GitHub Pages hosting here.
  2. Open index.html and copy everything between the <body> tags
  3. Paste that HTML wherever you would like inside your webpage
  4. Now you will need to tweak the styles and formatting to match the rest of your existing site.For an example of a modified version of of the HTML in this tutorial, see my sitehttp://nathanegraham.github.io/

    Notice that I have removed the image thumbnail and the excerpt. I’ve also moved the date before the post title.

» API, Data, Design, Tech Tips » Display WordPress Posts on Another...
On June 20, 2016
By
, ,

30 Responses to Display WordPress Posts on Another Site with WP REST API

  1. Ginnie says:

    Hi Nathan, great article! How did you achieve displaying the post’s date in human readable format instead of yyyy-mm-ddThh:ii:ssZ?

    • Hi Ginnie, Thanks! To parse the date I used something like the below, which you can find in the script.js file here:

      https://github.com/nathanegraham/wp-rest-api-post-getter/blob/master/script.js

      Does that answer your question?

      Note that I have my time and date format set like this:

      Time and Date settings


      Vue.filter('formatDate', function (date_str) {
      var year = date_str.substr(0,4),
      month = parseInt(date_str.substr(5,2)),
      day = date_str.substr(8,2),
      months = ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
      return months[month] + " " + day + ", "+year;
      });

  2. Mel says:

    Great article! I need to use {{item.featured_media}} for displaying the post thumbnail, but am only getting back the image id. I know I need to add and change parameters to vue.directive to make this work, but am not sure of the syntax to do so. Any advice? Thanks.

    • Mel says:

      Never mind, I figured this out. I am intending to use this for a slider and bring WordPress feeds into our University Drupal site. Thank you again for this code, and I will give kudos and credit of course. My code in progress: http://eres.geneseo.edu/test-api/index-eres.html

      • Very interesting. Looks like you’re off to a great start. So you’re looking to turn the featured image into a full width slider background and overlay the post title, date, and excerpt? Glad you found this helpful. I’ll definitely link to your version as another example when you’re done.

        • Leah says:

          Greetings Nathan: So far I have the API feed working on our campus video displays. https://www.geneseo.edu/sites/default/files/sites/library/staff-photos/leah-info/milne-entrance-display-700px.png

          A huge challenge is Drupal. No matter how I load the scripts, Drupal ignores the vue js and doesn’t render the feed. The feed renders fine on regular html and also in the video display. I have seen forum posts about similar issues with Drupal. I will keep you updated if I figure this out.

          • Leah says:

            Figured it out 🙂 https://www.geneseo.edu/library

            My college IT department had to grant me special editing permissions (JS/CSS) for our Drupal page. Glad it was nothing more complex than that! I am working on building a slider or rotator script, or styling the feed so there would be one large image and excerpt, followed by thumbnail and excerpts of the next 4-5 posts.

            Thank you so much!

          • Hi Leah,
            Very Nice! Any chance you can jot down your process here for folks who are using this with Drupal? This is timely because I’m going to be doing something similar on a homepage on a Drupal-based site next month.

  3. Leah says:

    Absolutely, Nathan. Do you have a preferred or additional method for communicatiing, ie Slack, GoToMeeting, Twitter ‘old fashioned’ email, etc? I apologize – I did not receive notification of a reply on this forum. I don’t want to miss anything.

    I can start documenting my process here . I am trying to figure out how to pull in tags from the feed and styling a post based on its tag. I may have more questions for you too.

  4. hifall says:

    Great post.

    I am trying to figure out how to use WP REST API to update a post under one of the sites in the network. Although I am using the correct credentials, I always get “Sorry, you are not allowed to edit this post.”. Do you have any idea why?

    Thanks!

    • Thanks! This is a good next post that I need to write. In this tutorial I’m just covering displaying posts on another site. Updating posts is a different matter. Can you describe your situation a bit more? You have a WP multisite network and you want a form on a child site to update a post on another child site on your network?

  5. Oli says:

    Nice post. Got things working but having issues with html characters being escaped in post titles. For example a post title containing ‘ shows up as ‘

    Have you encountered this before?

  6. Murtaza says:

    Hello Nathan
    Thank you for great tutorial I can now pull posts from another my website there are total 3500 posts is there is any way I can show 5 or 10 posts per page and add Number pagination to load next page Please see attached Screenshot.
    http://prntscr.com/fy7t6u

    I understand we can add parameters to url like this

    https://digitalborn.org/wp-json/wp/v2/posts/?page=2&per_page=5

    but if you can guide me how i can add pagination that would be great help.

    Thank you.

  7. M Lovett says:

    I am able to get my post info when I put my endpoint into the browser but when I put it into your script.js and open the index.html I am getting a blank page. Am I missing something?

    • It works for me still. You can take a look at the example I have up on github (linked in the article). Can you provide a link to your blank page?

      • M Lovett says:

        Here’s the link – Thanks for your help.

        https://nantucket.net/getter/index.html

        • Take a look at console by opening your page in Chrome -> right click -> select Inspect -> click Console. I see a couple issues that are likely causing your problem.

          For example, if I go here, there’s no route

          http://yesterdaysisland.com/wp-json/wp/v2/posts//posts?per_page=100&_jsonp=_jsonp3yeh6gd2ctu

          And the reason is because you have an extra “/posts” in there.

          • Miki says:

            Hi, This may be a duplicate but – I did see what you are talking about. I am copying the script.js below – thanks for your help.

            (function(){
            var endpoint = “http://yesterdaysisland.com/wp-json/wp/v2/posts”,
            itemsPerPage = 3,
            vm;

            Vue.directive(‘thumb’, function (val) {

            if(!val) return;
            var el = this.el;

            Vue.http.jsonp(endpoint+”/media”, {include:val},{jsonp: “_jsonp”}).then(function (response) {
            if(!response.data[0]) return;
            el.style.backgroundImage = “url(“+response.data[0].media_details.sizes.thumbnail.source_url+”)”;
            });

            });
            Vue.filter(‘removeMoreLink’, function (value) {
            return value.replace(/.+?/, ”);
            });

            Vue.filter(‘formatDate’, function (date_str) {
            var year = date_str.substr(0,4),
            month = parseInt(date_str.substr(5,2)),
            day = date_str.substr(8,2),
            months = [”, ‘January’, ‘February’, ‘March’, ‘April’, ‘May’, ‘June’, ‘July’, ‘August’, ‘September’, ‘October’, ‘November’, ‘December’];
            return months[month] + ” ” + day + “, “+year;
            });

            Vue.filter(‘more’, function (value, param) {
            return value.slice(0, param);
            });

            vm = new Vue({
            el: ‘#post_feed’,
            data: {
            items: [],
            loading: true,
            showed: itemsPerPage
            },
            methods:{
            showMore:function(){
            this.showed+=itemsPerPage;
            }
            },
            ready:function(){
            this.$http.jsonp(endpoint+”/posts”, {per_page:100},{jsonp: “_jsonp”}).then(function (response) {
            vm.items = response.data;
            vm.loading = false;
            });
            }
            });

            })();

  8. Hi Miki,

    This script looks okay on a quick glance. Could be a configuration issue somewhere else. I still see several errors when I visit your site linked above. You can try just removing “/posts” from your var endpoint line and see if that fixes it.

    • Miki says:

      That did not work.

      I am seeing many errors in the vue.resource.min.js file in DreamWeaver such as ‘Missing semicolon’ or ‘expected this and saw that’ etc.

      Is this a server configuration problem?

      • Miki says:

        OK, this is interesting. I just opened the index.html in Dtreaweaver in split screen and it showed the list perfectly including the images.

        Can you point me to what the server issue might be?

        Thanks

        • Miki says:

          OK – it’s working in Safari – not in Firefox. The later may be a caching issue.

          Thanks for your help. Consider this support issue closed – I’ll work on it from here.

          • Miki says:

            Me again – maybe it’s not closed. After checking various computers around the office, it is working everywhere but in Firefox on a Mac. Windows is fine.

            Miki

  9. Miki says:

    LAST TIME! – I have loaded this into the site proper and it is working on all browsers. I will now get out of your hair!!

    Thanks for your help and timely responses.

  10. Moreno says:

    Hi Nathan,
    thank you for your great post! I am experimenting the WP REST API in localhost and I’ve found that special characters (i.e. ‘&’ ) in the titles of the posts are not decoded. Is there a way to decode the titles?

Leave a Reply

Your email address will not be published. Required fields are marked *

« »