Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

Publicaciones sobre nikola (publicaciones antiguas, página 9)

Adding Support for a Markup to Nikola

One of the goals for Niko­la, my sta­tic si­te/­blog ge­ne­ra­tor is that it should be ea­sy to ex­ten­d. For exam­ple, to­day I added su­pport for two ma­rkup­s: tex­ti­le and Creo­leWiki.

Sin­ce Niko­la al­ready su­pported HT­M­L, reS­truc­tu­re­dText and Ma­rk­do­wn, adding a cou­ple mo­re is not ve­ry di­ffi­cul­t. He­re's ho­w:

  1. Crea­­te a .plu­­gin fi­­le like this one:

[Core]
Name = textile
Module = compile_textile

[Documentation]
Author = Roberto Alsina
Version = 0.1
Website = http://nikola.ralsina.me
Description = Compile Textile into HTML

Then you need to crea­te a py­thon mo­du­le ca­lled (in this ca­se) com­pi­le_­tex­ti­le.­py

That fi­le is boi­ler­pla­te plus two me­tho­d­s, com­pi­le_ht­ml and crea­te_­post

The com­pi­le_ht­ml me­thod takes two ar­gu­men­ts, one fi­le from whi­ch it rea­ds the ma­rku­p, and one to wri­te HT­M­L. Exam­ple:

def compile_html(self, source, dest):
    if textile is None:
        raise Exception('To build this site, you need to install the "textile" package.')
    try:
        os.makedirs(os.path.dirname(dest))
    except:
        pass
    with codecs.open(dest, "w+", "utf8") as out_file:
        with codecs.open(source, "r", "utf8") as in_file:
            data = in_file.read()
        output = textile(data, head_offset=1)
        out_file.write(output)

Make su­re to use utf8 eve­r­yhe­re.

The crea­te_­post func­tion is us­ed to crea­te a new, emp­ty, post wi­th so­me me­ta­da­ta in it. Exam­ple:

def create_post(self, path, onefile=False, title="", slug="", date="", tags=""):
    with codecs.open(path, "wb+", "utf8") as fd:
        if onefile:
            fd.write('<notextile>  <!--\n')
            fd.write('.. title: %s\n' % title)
            fd.write('.. slug: %s\n' % slug)
            fd.write('.. date: %s\n' % date)
            fd.write('.. tags: %s\n' % tags)
            fd.write('.. link: \n')
            fd.write('.. description: \n')
            fd.write('--></notextile>\n\n')
        fd.write("\nWrite your post here.")

The me­ta­da­ta has to be in the form ".. field­na­me: fiel­d­va­lue" and usua­lly nee­ds to be wra­pped in a co­m­ment so that it's not sho­wn in the ou­tpu­t.

The one­fi­le pa­ra­me­ter means you ha­ve to wri­te that me­ta­da­ta in the pos­t. If it's Fal­se, you do­n'­t.

In so­me ra­re ca­ses (Creo­le, I am looking at you) co­m­men­ts are not su­pported and you should rai­se an ex­cep­tion if one­fi­le is True.

And tha­t's it, ma­rkup su­pport is fair­ly ea­sy to add as long as the­re is a py­thon im­ple­men­ta­tion of a func­tion to con­vert ma­rkup in­to ht­m­l.

Client-rendered, one-URL, dynamic, static site.

My va­ca­tions end to­mo­rro­w. So, the ti­me to spend ha­cking fun, per­so­na­l, free stu­ff is going to be li­mited be­cau­se of the ti­me spent co­ding fun, free stu­ff for mo­ney. So, I de­ci­ded to fi­nish wi­th a bit of whi­ms­y.

I im­ple­men­ted a com­ple­te­ly clien­t-­ren­de­re­d, one-UR­L, dy­na­mic blo­g. Whi­ch is ac­tua­lly to­ta­lly sta­ti­c.

In fac­t, that blog is this blo­g, just wi­th a twis­t. If you go to this URL you wi­ll see wha­t's ba­si­ca­lly this ve­ry si­te, wi­th co­m­men­ts and eve­r­y­thing as usua­l. But if you cli­ck on "Pre­vious Pos­t" ... we­ll, it sta­ys in the sa­me pa­ge, even thou­gh it dis­pla­ys a di­ffe­rent post :-)

The ma­gic is the new, ex­pe­ri­men­ta­l, dy­na­mic ta­sk_­mus­ta­che plu­gin for my sta­tic si­te ge­ne­ra­to­r, Niko­la. whi­ch does the fo­llo­win­g:

  1. Ren­­ders post da­­ta as JSON fi­­les in­s­­tead of HT­­ML

  2. Crea­­tes a HT­­ML fi­­le that is rea­­lly a mus­­ta­­che.­­js te­m­­pla­­te

  3. Crea­­tes a HT­­ML fi­­le wi­­th so­­­me bi­­ts of Ja­­va­s­­cript that loads the te­m­­pla­­te and the newest po­s­­t's da­­ta.

  4. If you ac­­ce­ss that mus­­ta­­che.h­t­­ml wi­­th a fra­g­­men­­t, it uses that to fe­­tch JSON da­­ta and rew­­ri­­te itse­l­­f.

And tha­t's it. It ac­tua­lly loads fas­t, and re­ge­ne­ra­tes ve­ry fas­t, sin­ce it does mu­ch le­ss than the real si­te. The­re are a bun­ch of things that wi­ll dump you out of the "d­y­na­mi­c" si­te, like tag li­nks, and whate­ve­r, but it wo­rks sur­pri­sin­gly we­ll (and if you want to the­me it, it's just one tem­pla­te).

This is the first of a new kind of thing for Nikola, the "extra plugins". Basically, stuff that is too weird, specific or useless for the general distro, will go there, and to use those plugins, you have to create a plugins/ folder in your site and add it there manually.

En­jo­y!

Creating a Theme for Nikola From Scratch (almost)

The­re is so­me do­cu­men­ta­tion about crea­ting the­mes for Niko­la, but ma­y­be a tu­to­rial is al­so a use­ful way to ex­plain it. So, he­re it is. I'­ll ex­plain how to crea­te a the­me (al­mos­t) from scra­tch. Al­ter­na­ti­ve­l­y, you can take an exis­ting the­me and mo­di­fy on­ly par­ts of it via inhe­ri­tan­ce, but tha­t's for ano­ther do­cu­men­t.

I wi­ll try to crea­te a the­me that looks like Vi­ni­cius Ma­s­su­che­tto­'s Mo­nos­pa­ce The­me.

Leer más…

Nikola Feature-by-request: tag cloud!

I asked for fea­tu­re re­ques­ts for Niko­la my sta­tic si­te ge­ne­ra­to­r. I got so­me. One was from lon­g-­ti­me user Kay Ha­yen, so I just could­n't say no.

He asked for tag clou­d­s. Look:

An­y­thing in he­re wi­ll be re­pla­ced on bro­w­sers that su­pport the can­vas ele­ment

Cu­te, is­n't it? And it's rea­l, ac­tual tag da­ta from this ve­ry si­te. Wi­th li­nks!

How it's do­ne:

Niko­la ge­ne­ra­tes a JSON fi­le that has the cloud da­ta (tag na­me, si­ze, li­nk), and tha­t's pro­ce­ss­ed by JQue­ry and ta­gCan­vas and ... we­ll, it wo­rks.

You have to add jquery.tagcanvas.min.js somewhere and embed a whole pile of raw HTML (see here for details) but hey, it works.

Ho­pe you are ha­pp­y, Ka­y, you ma­de me co­de ja­vas­cript, du­de ;-)

It's pro­ba­bly ra­ther "ea­s­y" to make it use any of the­se ins­tead of ta­gCan­vas if an­yo­ne is so in­cli­ne­d.


Contents © 2000-2024 Roberto Alsina