Skip to main content

Ralsina.Me — Roberto Alsina's website

Posts about nikola (old posts, page 1)

Nikola 1.2 is out!

Ver­sion 1.2 of Niko­la, my stat­ic site gen­er­a­tor and the soft­ware be­hind this very site, is out!

Why build stat­ic sites? Be­cause they are light in re­sources, they are fu­ture-proof, be­cause it's easy, be­cause they are safe, and be­cause you avoid lockin.

New Fea­tures:

  • Im­age gallery (just drop pics on a fold­er)

  • Built-in web­serv­er for pre­views (doit -a serve)

  • Helper com­mands to cre­ate new posts (doit -a new_­­post)

  • Google Sitemap sup­­port

  • A Hand­­book!

  • Full de­­mo site in­­­clud­ed

  • Sup­port for au­to­mat­ic de­ploy­ment (doit -a de­­ploy)

  • Clien­t-­­side redi­rec­­tions

And of course the old fea­tures:

  • Write your posts in re­Struc­­tured text

  • Clean, cus­­tom­iz­a­ble page de­sign (via boot­s­trap)

  • Com­­ments via Dis­­qus

  • Sup­­port any an­a­­lyt­ics you want

  • Build blogs with tags, feed­s, feeds for your tags, in­­dex­es, and more

  • Works like a sim­­ple CMS for things out­­­side your blog

  • Clean cus­­tom­iz­a­ble tem­­plates us­ing Mako

  • Pure python, and not a lot of it (about 600 lines)

  • Smart builds (doit on­­ly re­builds changed pages)

  • Easy to ex­­tend and im­prove

  • Code dis­­­played with syn­­tax high­­­light­ing

Right now Niko­la does lit­er­al­ly ev­ery­thing I need, so if you try it and need some­thing else... it's a good time to ask!

More in­fo at http://niko­la-­gen­er­a­tor.­google­code.­com

Nikola 1.1 is out!

A sim­ple yet pow­er­ful and flex­i­ble stat­ic web­site and blog gen­er­a­tor, based on doit, mako, do­cu­tils and boot­strap.

I built this to pow­er this very site you are read­ing, but de­cid­ed it may be use­ful to oth­er­s. The main goals of Niko­la are:

  • Small code­base: be­­cause I don't want to main­­tain a big thing for my blog

  • Fast page gen­er­a­­tion: Adding a post should not take more that 5 sec­onds to build.

  • Stat­ic out­­put: De­­ploy­­ment us­ing rsync is smooth.

  • Flex­i­ble page gen­er­a­­tion: you can de­­cide where ev­ery­thing goes in the fi­­nal site.

  • Pow­er­­ful tem­­plates: Us­es Mako

  • Clean markup for post­s: Us­es Do­cu­tils

  • Don't do stupid build­s: Us­es doit

  • Clean HTML out­­put by de­­fault: Us­es boot­s­trap

  • Com­­ments out of the box: Us­es Dis­­qus

  • Tags, with their own RSS feeds

  • Easy way to do a blog

  • Stat­ic pages out­­­side the blog

  • Mul­ti­lin­gual blog sup­­port (my own blog is en­g­lish + span­ish)

I think this ini­tial ver­sion achieves all of those goal­s, but of course, it can be im­proved. Feed­back is very wel­come!

Niko­la's home page is cur­rent­ly http://niko­la-­gen­er­a­tor.­google­code.­com

How it's done

I added a very mi­nor fea­ture to the site. Up here ^ you should be able to see a link that says "reSt". If you click on it, it will show you the "source code" for the page.

I did this for a few rea­son­s:

  1. Be­­cause a com­­ment seemed to sug­­gest it ;-)

  2. Be­­cause it seems like a nice thing to do. Since I so like reSt, I would like oth­­ers to use it, too. And show­ing how easy it is to write us­ing it, is cool.

  3. It's the "free soft­­ware-y" thing to do. I am pro­vid­ing you the pre­­ferred way to mod­­i­­fy my post­s.

  4. It was ridicu­lous­­ly easy to ad­d.

Al­so, if you see some­thing miss­ing, or some­thing you would like to have on the site, please com­men­t, I will try to add it.

Nikola is Near

I man­aged to do some mi­nor work to­day on Niko­la, the stat­ic web­site gen­er­a­tor used to gen­er­ate ... well, this stat­ic web­site.

  • Im­­ple­­men­t­ed tags (in­­clud­ing per-­­tag RSS feed­s)

  • Sim­­pli­­fied tem­­plates

  • Sep­a­rat­ed code and con­­fig­u­ra­­tion.

The last one was the trick­i­est. And as a teaser, here is the full con­fig­u­ra­tion file to cre­ate this site, ex­cept HTML bits for an­a­lyt­ic­s, google cus­tom search and what­ev­er that would make no sense on oth­er sites. I hope it's some­what clear.

# -*- coding: utf-8 -*-

# post_pages contains (wildcard, destination, template) tuples.
#
# The wildcard is used to generate a list of reSt source files (whatever/thing.txt)
# That fragment must have an associated metadata file (whatever/thing.meta),
# and opcionally translated files (example for spanish, with code "es"):
#     whatever/thing.txt.es and whatever/thing.meta.es
#
# From those files, a set of HTML fragment files will be generated:
# whatever/thing.html (and maybe whatever/thing.html.es)
#
# These files are combinated with the template to produce rendered
# pages, which will be placed at
# output / TRANSLATIONS[lang] / destination / pagename.html
#
# where "pagename" is specified in the metadata file.
#

post_pages = (
    ("posts/*.txt", "weblog/posts", "post.tmpl"),
    ("stories/*.txt", "stories", "post.tmpl"),
)

# What is the default language?

DEFAULT_LANG = "en"

# What languages do you have?
# If a specific post is not translated to a language, then the version
# in the default language will be shown instead.
# The format is {"translationcode" : "path/to/translation" }
# the path will be used as a prefix for the generated pages location

TRANSLATIONS = {
    "en": "",
    "es": "tr/es",
    }

# Data about this site
BLOG_TITLE = "Lateral Opinion"
BLOG_URL = "//ralsina.me"
BLOG_EMAIL = "ralsina@kde.org"
BLOG_DESCRIPTION = "I write free software. I have an opinion on almost "\
    "everything. I write quickly. A weblog was inevitable."

# Paths for different autogenerated bits. These are combined with the translation
# paths.

# Final locations are:
# output / TRANSLATION[lang] / TAG_PATH / index.html (list of tags)
# output / TRANSLATION[lang] / TAG_PATH / tag.html (list of posts for a tag)
# output / TRANSLATION[lang] / TAG_PATH / tag.xml (RSS feed for a tag)
TAG_PATH = "categories"
# Final location is output / TRANSLATION[lang] / INDEX_PATH / index-*.html
INDEX_PATH = "weblog"
# Final locations for the archives are:
# output / TRANSLATION[lang] / ARCHIVE_PATH / archive.html
# output / TRANSLATION[lang] / ARCHIVE_PATH / YEAR / index.html
ARCHIVE_PATH = "weblog"
# Final locations are:
# output / TRANSLATION[lang] / RSS_PATH / rss.xml
RSS_PATH = "weblog"

# A HTML fragment describing the license, for the sidebar.
LICENSE = """
    <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/ar/">
    <img alt="Creative Commons License" style="border-width:0; margin-bottom:12px;"
    src="http://i.creativecommons.org/l/by-nc-sa/2.5/ar/88x31.png"></a>
"""

# A search form to search this site, for the sidebar. Has to be a <li>
# for the default template (base.tmpl).
SEARCH_FORM = """
    <!-- google custom search -->
    <!-- End of google custom search -->
"""

# Google analytics or whatever else you use. Added to the bottom of <body>
# in the default template (base.tmpl).
ANALYTICS = """
        <!-- Start of StatCounter Code -->
        <!-- End of StatCounter Code -->
        <!-- Start of Google Analytics -->
        <!-- End of Google Analytics -->
"""

# Put in global_context things you want available on all your templates.
# It can be anything, data, functions, modules, etc.
GLOBAL_CONTEXT = {
    'analytics': ANALYTICS,
    'blog_title': BLOG_TITLE,
    'blog_url': BLOG_URL,
    'translations': TRANSLATIONS,
    'license': LICENSE,
    'search_form': SEARCH_FORM,
    # Locale-dependent links
    'archives_link': {
        'es': '<a href="/tr/es/weblog/archive.html">Archivo</a>',
        'en': '<a href="/weblog/archive.html">Archives</a>',
        },
    'tags_link': {
        'es': '<a href="/tr/es/categories/index.html">Tags</a>',
        'en': '<a href="/categories/index.html">Tags</a>',
        },
    }

execfile("nikola/nikola.py")

Welcome To Nikola

If you see this, you may no­tice some changes in the site.

So, here is a short ex­pla­na­tion:

  • I changed the soft­­ware and the tem­­plates for this blog.

  • Yes, it's a work in progress.

  • The new soft­­ware is called Niko­la.

  • Yes, it's pret­­ty cool.

Why change?

Are you kid­ding? My pre­vi­ous blog-­gen­er­a­tor (Son of Bartle­Blog) was not in good shape. The ar­chives on­ly cov­ered 2000-2010, the "pre­vi­ous post­s" links were a lot­tery, and the span­ish ver­sion of the site was miss­ing whole sec­tion­s.

So, what's Nikola?

Niko­la is a stat­ic web­site gen­er­a­tor. One thing about this site is that it is, and has al­ways been, just HTM­L. Ev­ery "dy­nam­ic" thing you see in it, like com­ments, is a third par­ty ser­vice. This site is just a bunch of HTML files sit­ting in a fold­er.

So, how does Nikola work?

Niko­la takes a fold­er full of txt files writ­ten in re­struc­tured text, and gen­er­ates HTML frag­ments.

Those frag­ments plus some light meta­da­ta (ti­tle, tags, de­sired out­put file­name, ex­ter­nal links to sources) and Some Mako Tem­plates cre­ate HTML pages.

Those HTML pages use boot­strap to not look com­plete­ly bro­ken (hey, I nev­er claimed to be a de­sign­er).

To make sure I don't do use­less work, doit makes sure on­ly the re­quired files are recre­at­ed.

Why not use <whatever>?

Be­cause, for di­verse rea­son­s, I want­ed to keep the ex­act URLs I have been us­ing:

  • If I move a page, keep­­ing the Dis­­qus com­­ments at­­tached gets tricky

  • Some peo­­ple may have book­­marked them

Al­so, I want­ed:

  • Mako tem­­plates (be­­cause I like Mako)

  • Re­struc­­tured text (Be­­cause I have over 1000 posts writ­ten in it)

  • Python (so I could hack it)

  • Easy to hack (cur­ren­t­­ly Niko­la is un­der 600 LOC, and is al­­most fea­­ture com­­plete)

  • Sup­­port for a mul­ti­lin­gual blog like this one.

And of course:

  • It sound­ed like a fun, short pro­jec­t. I had the sus­pi­­cion that with a bit of glue, ex­ist­ing tools did 90% of the work. Looks like I was right, since I wrote it in a few days.

Are you going to maintain it?

Sure, since I am us­ing it.

Is it useful for other people?

Prob­a­bly not right now, be­cause it makes a ton of as­sump­tions for my site. I need to clean it up a bit be­fore it's re­al­ly nice.

Can other people use it?

Of course. It will be avail­able some­where soon.

Missing features?

No tags yet. Some oth­er mi­nor miss­ing things.


Contents © 2000-2023 Roberto Alsina