2013-08-28 20:09

New in Nikola v6 part II: We Love Javascript

I am planning to do a major release (version 6!) of Nikola my static blog and site generator the next weekend. It's a major version because there has been a ton of feature work done. So, I will do a quick series highlighting some of those improvements this week.

Today's Topic: Javascript

So, Nikola builds static pages. Like I often say, that doesn't mean they have to be boring. IN this release, Nikola's templates are organized in such a way that it's easy to create complex javascript-based layouts. Let's see an example.

Yesterday I showed you a nicely typeset page containing A Study in Scarlet. If you have not seen it yet, check it out, it has typographical quotes and dashes, justified text and hyphenation.

In fact, if you resize your window to be "phone-sized" it works quite comfortably as a way to read. I would say the text layout is better than in the Kindle for Android app, for instance.

So, what about going further in that direction? Why not make that specific webpage work more like an ebook reader? Indeed let's do that!

First, we need to use a custom template for that specific page. That's easy using the template page metadata:

.. date: 2013/08/27 18:20:55
.. slug: a-study-in-scarlet
.. template: ebook.tmpl


By A. Conan Doyle [1]_

And now, the fun part: let's do a very hackish JQuery script to make it look like an ebook reader! You have to put this code in templates/ebook.tmpl in your site. Code offered without comments mostly out of shame because I suck at JS:

## -*- coding: utf-8 -*-
<%inherit file="post.tmpl"/>
<%block name="extra_head">
<%block name="content">
<div id="container" style="overflow:hidden; width: 100%;">
<div id="paginate">
%if title:
<div class="pagination" style="width:100%; text-align: center;">
    <a href="#" class="previous" data-action="previous">&lsaquo;</a>
    <input type="text" readonly="readonly" />
    <a href="#" class="next" data-action="next">&rsaquo;</a>

<%block name="extra_js">
<script src="http://beneverard.github.io/jqPagination/js/jquery.jqpagination.js"></script>
var split_count=1;
var ready = false;
function current_page() {
// returns the current page, zero-based
    return Math.floor(($('#container').scrollLeft() +1) / $('#container').width())

    split_count = Math.ceil($('#paginate').height() / ($('#container').height()))+2;
    $('#paginate').css('-webkit-column-count', ''+split_count);
    $('#paginate').width(split_count * $('#container').width());
        max_page: split_count,
        paged: function(page) {
            if (current_page() != page-1 && page >= 1)
                $('#container').animate({scrollLeft: (page-1)*$('#container').width()}, 400);
                location.hash = 'page---'+page;
    ready = true;

    //$('.pagination').jqPagination('option', 'current_page', current_page()+1)

function hash_handler() {
if (ready && location.hash) {
        if (location.hash.slice(0,8) == '#page---') {
            page = parseInt(location.hash.slice(8));
        else {
            target = $(location.hash);
            w = $('#container').width();
            page = Math.ceil((target.position().left-target.height()+ $('#container').scrollLeft())/w);
        if (page >= 1) {
            $('.pagination').jqPagination('option', 'current_page', page);
$(window).on('hashchange', hash_handler);

Before showing you the end result, list of known bugs!

  • If you resize your window, the layout doesn't adjust.
  • If you resize your window, the number of pages changes.
  • Some chapters' links miss by a page in either direction.
  • No keyboard shortcuts.
  • It only sort-of-works in chrome and maybe other webkit-based browsers

And here is the end result. Enjoy!


Comments powered by Disqus

Contents © 2000-2019 Roberto Alsina