Skip to main content

Ralsina.Me — Roberto Alsina's website

Posts about nikola (old posts, page 9)

Adding Support for a Markup to Nikola

One of the goals for Niko­la, my stat­ic site/blog gen­er­a­tor is that it should be easy to ex­tend. For ex­am­ple, to­day I added sup­port for two markup­s: tex­tile and Cre­oleWi­ki.

Since Niko­la al­ready sup­port­ed HTM­L, re­Struc­tured­Text and Mark­down, adding a cou­ple more is not very dif­fi­cult. Here's how:

  1. Cre­ate a .plug­in file 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 cre­ate a python mod­ule called (in this case) com­pile_­tex­tile.py

That file is boil­er­plate plus two meth­od­s, com­pile_html and cre­ate_­post

The com­pile_html method takes two ar­gu­ments, one file from which it reads the markup, and one to write HTM­L. Ex­am­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 sure to use ut­f8 ev­ery­here.

The cre­ate_­post func­tion is used to cre­ate a new, emp­ty, post with some meta­da­ta in it. Ex­am­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 meta­da­ta has to be in the form ".. field­name: field­val­ue" and usu­al­ly needs to be wrapped in a com­ment so that it's not shown in the out­put.

The one­file pa­ram­e­ter means you have to write that meta­da­ta in the post. If it's False, you don't.

In some rare cas­es (Cre­ole, I am look­ing at you) com­ments are not sup­port­ed and you should raise an ex­cep­tion if one­file is True.

And that's it, markup sup­port is fair­ly easy to add as long as there is a python im­ple­men­ta­tion of a func­tion to con­vert markup in­to htm­l.

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

My va­ca­tions end to­mor­row. So, the time to spend hack­ing fun, per­son­al, free stuff is go­ing to be lim­it­ed be­cause of the time spent cod­ing fun, free stuff for mon­ey. So, I de­cid­ed to fin­ish with a bit of whim­sy.

I im­ple­ment­ed a com­plete­ly clien­t-ren­dered, one-URL, dy­nam­ic blog. Which is ac­tu­al­ly to­tal­ly stat­ic.

In fac­t, that blog is this blog, just with a twist. If you go to this URL you will see what's ba­si­cal­ly this very site, with com­ments and ev­ery­thing as usu­al. But if you click on "Pre­vi­ous Post" ... well, it stays in the same page, even though it dis­plays a dif­fer­ent post :-)

The mag­ic is the new, ex­per­i­men­tal, dy­nam­ic task_­mus­tache plug­in for my stat­ic site gen­er­a­tor, Niko­la. which does the fol­low­ing:

  1. Ren­ders post da­­ta as JSON files in­­stead of HTML

  2. Cre­ates a HTML file that is re­al­­ly a mus­­tache.js tem­­plate

  3. Cre­ates a HTML file with some bits of Javascript that loads the tem­­plate and the new­est post's da­­ta.

  4. If you ac­cess that mus­­tache.html with a frag­­men­t, it us­es that to fetch JSON da­­ta and re­write it­­self.

And that's it. It ac­tu­al­ly loads fast, and re­gen­er­ates very fast, since it does much less than the re­al site. There are a bunch of things that will dump you out of the "dy­nam­ic" site, like tag links, and what­ev­er, but it works sur­pris­ing­ly well (and if you want to theme it, it's just one tem­plate).

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­joy!

Creating a Theme for Nikola From Scratch (almost)

There is some doc­u­men­ta­tion about cre­at­ing themes for Niko­la, but maybe a tu­to­ri­al is al­so a use­ful way to ex­plain it. So, here it is. I'll ex­plain how to cre­ate a theme (al­most) from scratch. Al­ter­na­tive­ly, you can take an ex­ist­ing theme and mod­i­fy on­ly parts of it via in­her­i­tance, but that's for an­oth­er doc­u­men­t.

I will try to cre­ate a theme that looks like Vini­cius Mas­suchet­to's Monospace Theme.

Read more…

Nikola Feature-by-request: tag cloud!

I asked for fea­ture re­quests for Niko­la my stat­ic site gen­er­a­tor. I got some. One was from long-­time us­er Kay Hayen, so I just could­n't say no.

He asked for tag cloud­s. Look:

Any­thing in here will be re­placed on browsers that sup­port the can­vas el­e­ment

Cute, is­n't it? And it's re­al, ac­tu­al tag da­ta from this very site. With links!

How it's done:

Niko­la gen­er­ates a JSON file that has the cloud da­ta (tag name, size, link), and that's pro­cessed by JQuery and tag­Can­vas and ... well, it work­s.

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.

Hope you are hap­py, Kay, you made me code javascript, dude ;-)

It's prob­a­bly rather "easy" to make it use any of these in­stead of tag­Can­vas if any­one is so in­clined.


Contents © 2000-2023 Roberto Alsina