Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

New in Nikola v6 part II: We Love Javascript

I am plan­ning to do a ma­jor re­lea­se (ver­sion 6!) of Niko­la my sta­tic blog and si­te ge­ne­ra­tor the next weeken­d. It's a ma­jor ver­sion be­cau­se the­re has been a ton of fea­tu­re wo­rk do­ne. So, I wi­ll do a qui­ck se­ries hi­gh­li­gh­ting so­me of tho­se im­pro­ve­men­ts this week.

Today's Topic: Javascript

So, Niko­la buil­ds sta­tic pa­ges. Like I often sa­y, that does­n't mean they ha­ve to be bo­ring. IN this re­lea­se, Niko­la's tem­pla­tes are or­ga­ni­zed in su­ch a way that it's ea­sy to crea­te com­plex ja­vas­crip­t-­ba­sed la­you­ts. Le­t's see an exam­ple.

Yes­ter­day I sho­wed you a ni­ce­ly ty­pes­et pa­ge con­tai­ning A Study in Scar­le­t. If you ha­ve not seen it ye­t, che­ck it ou­t, it has ty­po­gra­phi­cal quo­tes and das­he­s, jus­ti­fied text and hy­phe­na­tio­n.

In fac­t, if you re­si­ze your win­dow to be "pho­ne-­si­ze­d" it wo­rks qui­te co­m­for­ta­bly as a way to rea­d. I would say the text la­yout is be­tter than in the Kind­le for An­droid app, for ins­tan­ce.

So, what about going fur­ther in that di­rec­tio­n? Why not make that spe­ci­fic we­bpa­ge wo­rk mo­re like an ebook rea­de­r? In­deed le­t's do tha­t!

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
.. title: A STUDY IN SCARLET.
.. slug: a-study-in-scarlet
.. template: ebook.tmpl

===================
A STUDY IN SCARLET.
===================

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>
<%block name="content">
<div id="container" style="overflow:hidden; width: 100%;">
<div id="paginate">
%if title:
    <h1>${title}</h1>
%endif
    ${post.text()}
</div>
</div>
<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>
</div>
</%block>

<%block name="extra_js">
<script src="http://beneverard.github.io/jqPagination/js/jquery.jqpagination.js"></script>
<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())
}

$(document).ready(function(){
    $('#container').height($(window).height()-150-$('.pagination').height());
    split_count = Math.ceil($('#paginate').height() / ($('#container').height()))+2;
    $('#paginate').css('-webkit-column-count', ''+split_count);
    $('#paginate').width(split_count * $('#container').width());
    $('#paginate').height($('#container').height());
    $('.pagination').jqPagination({
        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;
    hash_handler();
});

$('#container').scroll(function(){
    //$('.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);
</script>
</%block>

Be­fo­re sho­wing you the end re­sul­t, list of kno­wn bugs!

  • If you re­­si­­ze your wi­n­­do­­w, the la­­yout does­n't adjus­­t.

  • If you re­­si­­ze your wi­n­­do­­w, the nu­m­­ber of pa­­ges chan­­ges.

  • So­­­me cha­p­­te­r­s' li­nks miss by a pa­­ge in ei­­­ther di­­re­c­­tio­­n.

  • No ke­­y­­board sho­r­­tcu­­ts.

  • It on­­ly so­r­­t-o­­­f-wo­­­rks in ch­­ro­­­me and ma­­y­­be other we­­bki­­t-­­ba­s­ed bro­­w­­sers

And he­re is the end re­sult. En­jo­y!

Gustavo Bragança / 2013-08-29 03:03:

Nicely done! Maybe I could put my future thesis on this. How it would handle figures?

Roberto Alsina / 2013-08-29 10:28:

There is a figure directive (http://docutils.sourceforge... but it doesn't do things like figure indexes and cross referencing.

Gustavo Bragança / 2013-08-31 02:59:

Ah, it is on .rst. I saw this jQuery code and got lost. I am just starting a Nikola blog and I am still getting used to it.

Nice job, Roberto!


Contents © 2000-2023 Roberto Alsina