One of the changes I made recently to this site is the addition of the "Five Random Posts" area on the left sidebar. Here's a screenshot in case I decide to change my layout later:

A screenshot of this site, with the

I use Ghost as my blogging engine, and recently they've unveiled a public API that allows theme users to query Ghost's data to retrieve posts, tags, authors and such. I've long wanted a feature on my blog to highlight some of my previous work, and with the reveal of the API, I finally had the ability to build one. Here's hoping someone else out there finds this useful too.

NOTE: There's a BIG caveat to the following post: Ghost's public API is still in beta, and (at the time of writing) they explicitly warn against using this feature in production. I, of course, am ignoring them.

The Finished Code

I like to show results first. Here's the complete Javascript code that queries the Ghost API:

<script>  
    $(document).ready(function () {
        $.get(
            ghost.url.api('posts', {limit: 'all'})
        ).done(onSuccess);
    });

    function onSuccess(data) {
        var $result = $('#featured-posts-list');
        var sortedPosts = shuffleArray(data.posts);
        var displayPosts = sortedPosts.slice(0,5);
        $.each(displayPosts, function (i, post) {
            $result.append(
                '<li><i class="fa fa-star"></i><a href="http://www.exceptionnotfound.net' + post.url + '">' + post.title + '</a></li>'
            );
        });
    }

    function shuffleArray(array) {
        for (var i = array.length - 1; i > 0; i--) {
            var j = Math.floor(Math.random() * (i + 1));
            var temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }
        return array;
    }
</script>  

Now, let's see how we got to this point.

Prerequisites

Before we can even use the Public API, we must enable it in Ghost by going to the Labs page of the admin site and clicking the appropriate checkbox:

A screenshot of Ghost's Admin site for my blog, with the

We now need to set the requirements for using the ghost.url.api(). The docs for this feature state the following:

There are 3 pre-requisites that are required in order to use this helper:

  1. {{ghost_head}} helper must be present in your theme.
  2. Public API access enabled in Admin-UI.
  3. You must not have disabled the ghost-frontend client (only accessible via the DB)

We've already accomplished #2, so ensure that #1 and #3 are true for your theme and you should be good to go.

Step 1: Getting All Posts from Ghost

The first and most critical step of this entire process is to get the posts from the Ghost API. We do this in the following function:

$(document).ready(function () {
    $.get(
        ghost.url.api('posts', {limit: 'all'})
    ).done(onSuccess);
});

The ghost.url.api() function takes two parameters. The first parameter states what kind of data we are querying for. In our case, we want 'posts' but this could be 'tags' or 'authors'. The second parameter is a collection of options for the query. Some of these options include:

  • limit: Specifies maximum number of items to return. Default is 15, can specify 'all' to return all items found.
  • order: Specifies a column by which to order the results. For example, you could say order: 'published_at' to return the posts in published order.
  • filter: Allows you to specify how to filter results. For example, you could get all featured posts, or get all posts in a specific tag. See the docs for more info.

For this operation, we only need the "limit" option, and we set it to 'all'.

Step 2: Randomizing the Posts

Now that we've got all the posts from the Ghost API, we need to select a random subset of them. For this demo, we want to display 5 random posts.

First off, we need a method by which we can randomize the order of the posts in the array. The best way to do this is via a shuffling algorithm, and the most common of these is the Fisher-Yates shuffle. The resulting function looks like this (modified from this StackOverflow answer):

function shuffleArray(array) {  
    for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    return array;
}

Step 3: Displaying the 5 Random Posts

After randomizing the array of posts, I now need to select the first 5 and display them using JavaScript's slice() method and jQuery's each() and append() methods. That is what the following function does:

function onSuccess(data) {  
    var $result = $('#featured-posts-list');
    var sortedPosts = shuffleArray(data.posts);
    var displayPosts = sortedPosts.slice(0,5);
    $.each(displayPosts, function (i, post) {
        $result.append(
            '<li><i class="fa fa-star"></i><a href="http://www.exceptionnotfound.net' + post.url + '">' + post.title + '</a></li>'
        );
    });
}

This function shuffles the posts, takes the first 5 from the shuffled set, then appends them to a waiting <ul id='featured-posts-list'> element.

Summary

That's it! We now have a system by which we can display 5 random posts in our Ghost theme! If you want to see a demo, well, you're already looking at one (unless I've changed my layout, in which case, see the screenshot above).

One possible downside to this method is that I don't know how performant it will be given a large set of posts. The objects returned by the ghost.url.api() method can get fairly large, so performance could be an issue on some blogs.

Anyway, if this helped you out, feel free to share in the comments.

Happy Coding!