How to add pagination to Ghost using Javascript

How to add pagination to Ghost using Javascript

One of the things that are nice to have on a blog is an easy navigation; Ghost provides two buttons to go to the previous post and another for go to the newest post, but it doesn't have pagination by default.

So I decided to use some variables that Ghost provides to create a pagination, these are the steps you need to follow to generate a custom pagination:

Create a partial file

If you are using Casper which is the default Ghost theme, it uses a partial file to show the pagination, so we are going to overwrite the content creating a pagination.hbs file inside Partial, this is the content for the partial file:

<div style="display: none;">
    <span class="curr-page">{{page}}</span>
    <span class="total-pages">{{pages}}</span>
</div>

<ul class="pagination text-center" role="navigation" aria-label="Pagination">
    {{#if prev}}
        <li class="pagination-previous"><a href="{{page_url prev}}">Previous</a></li>
    {{else}}
        <li class="pagination-previous disabled">Previous</li>
    {{/if}}
    {{#if next}}
        <li class="pagination-next"><a href="{{page_url next}}">Next</a></li>
    {{else}}
        <li class="pagination-next disabled">Next</li>
    {{/if}}
</ul>

The code on pagination.hbs will provide the current page and the total of pages, these values will be used in the javascript code.

The pagination code with previous and next button are inside the pagination class.

The classes are coming from foundation which is the framework that I use on this blog; you also can use Bootstrap classes.

Generate pagination numbers

To create the pagination is necessary to use Javascript. I used a simple algorithm that I found on Gist.

You can put this code in the Blog Footer using Code Injection in the Ghost console or if you are using casper inside casper/assets/js/index.js or in your custom javascript file.

// Source: https://gist.github.com/kottenator/9d936eb3e4e3c3e02598
function pagination(c, m) {
    var current = c,
        last = m,
        delta = 2,
        left = current - delta,
        right = current + delta + 1,
        range = [],
        rangeWithDots = [],
        l;

    for (var i = 1; i <= last; i++) {
        if (i == 1 || i == last || i >= left && i < right) {
            range.push(i);
        }
    }

    for (var arr = range, isArray = Array.isArray(arr), i = 0, arr = isArray ? arr : arr[Symbol.iterator]();;) {
        var ref;

        if (isArray) {
            if (i >= arr.length) break;
            ref = arr[i++];
        } else {
            i = arr.next();
            if (i.done) break;
            ref = i.value;
        }

        var n = ref;

        if (l) {
            if (n - l === 2) { rangeWithDots.push(l + 1); }
            else if (n - l !== 1) { rangeWithDots.push('...'); }
        }
        rangeWithDots.push(n);
        l = n;
    }

    return rangeWithDots;
}

Now we need to insert pass the parameters to the pagination function, the first one is the current page, and the last one is the total of pages. In this javascript code we pass both values and append the numbers to our pagination:

function createPagination() {
    var currentPage = parseInt($('.curr-page').text()),
        totalPages = parseInt($('.total-pages').text());
    var url = window.location.href;

    if(totalPages > 1) {
        var paginationArr = pagination(currentPage, totalPages);
        var paginationItem;
        var isCurrent = '';

        for (var i = paginationArr.length - 1; i >= 0; i--) {
        var pageNum = paginationArr[i];

        if (pageNum === currentPage) {
                paginationItem = '<li class="current">' + pageNum + '</li>';
            } else if (typeof pageNum === 'number') {
                var urlArray = url.split('/');
                if(urlArray[urlArray.length - 3] === 'page') {
                    url = url.replace(/\/page\/.*$/,'') + '/';
                }
                paginationItem = '<li>' +
                    '<a href=\"' + url + 'page/' + pageNum + '\" aria-label=\"Page ' + pageNum + '\">'
                    + pageNum + '</a>' +
                    '</li>';
            } else {
                paginationItem = '<li class=\"ellipsis\"></li>';
            }
            $('.pagination-previous').after(paginationItem);
        }
    } else {
        $('.pagination').css('display', 'none');
    }
}
createPagination();

After that, you will see the custom pagination on your blog.