Nikola is a static website and blog generator. The very short explanation is that it takes some texts you wrote, and uses them to create a folder full of HTML files. If you upload that folder to a server, you will have a rather full-featured website, done with little effort.
It's original goal is to create blogs, but it supports most kind of sites, and can be used as a CMS, as long as what you present to the user is your own content instead of something the user generates.
Nikola can do:
Since Nikola-based sites don't run any code on the server, there is no way to process user input in forms.
Nikola can't do:
Keep in mind that "static" doesn't mean boring. You can have animations, slides or whatever fancy CSS/HTML5 thingie you like. It only means all that HTML is generated already before being uploaded. On the other hand, Nikola sites will tend to be content-heavy. What Nikola is good at is at putting what you write out there.
Most "modern" websites are dynamic in the sense that the contents of the site live in a database, and are converted into presentation-ready HTML only when a user wants to see the page. That's great. However, it presents some minor issues that static site generators try to solve.
In a static site, the whole site, every page, everything, is created before the first user even sees it and uploaded to the server as a simple folder full of HTML files (and images, CSS, etc).
So, let's see some reasons for using static sites:
Dynamic sites are prone to experience security issues. The solution for that is constant vigilance, keeping the software behind the site updated, and plain old good luck. The stack of software used to provide a static site, like those Nikola generates, is much smaller (Just a webserver).
A smaller software stack implies less security risk.
If you create a site using (for example) Wordpress, what happens when Wordpress releases a new version? You have to update your Wordpress. That is not optional, because of security and support issues. If I release a new version of Nikola, and you don't update, nothing happens. You can continue to use the version you have now forever, no problems.
Also, in the longer term, the very foundations of dynamic sites shift. Can you still deploy a blog software based on Django 0.96? What happens when your host stops supporting the php version you rely on? And so on.
You may say those are long term issues, or that they won't matter for years. Well, I believe things should work forever, or as close to it as we can make them. Nikola's static output and its input files will work as long as you can install a Python > 2.5 (soon 3.x) in a Linux, Windows, or Mac and can find a server that sends files over HTTP. That's probably 10 or 15 years at least.
Also, static sites are easily handled by the Internet Archive.
On dynamic sites, every time a reader wants a page, a whole lot of database queries are made. Then a whole pile of code chews that data, and HTML is produced, which is sent to the user. All that requires CPU and memory.
On a static site, the highly optimized HTTP server reads the file from disk (or, if it's a popular file, from disk cache), and sends it to the user. You could probably serve a bazillion (technical term) pageviews from a phone using static sites.
On server-side blog platforms, sometimes you can't export your own data, or it's in strange formats you can't use in other services. I have switched blogging platforms from Advogato to PyCs to two homebrewed systems, to Nikola, and have never lost a file, a URL, or a comment. That's because I have always had my own data in a format of my choice.
With Nikola, you own your files, and you can do anything with them.
Nikola has a very defined featureset: it has every feature I needed for my own sites. Hopefully, it will be enough for others, and anyway, I am open to suggestions.
If you want to create a blog or a site, Nikola provides:
This is currently lacking on detail. Considering the niche Nikola is aimed at, I suspect that's not a problem yet. So, when I say "get", the specific details of how to "get" something for your specific operating system are left to you.
Any non-prehistorical version of the above should work, but the newer the better.
Then get Nikola itself (TODO add link), unzip it, and rename the folder nikola-x.y to the name of your site.
To create posts and pages in Nikola, you write them in restructured text, a light markup that is later converted to HTML (I may add support for textile or other markups later). There is a great quick tutorial to learn restructured text
First, let's see how you "build" your site. Nikola comes with a minimal site to get you started.
The tool used to do builds is called doit, and it rebuilds the files that are not up to date, so your site always reflects your latest content. To do our first build, just run "doit":
$ doit Parsing metadata . render_posts:stories/manual.html . render_posts:posts/1.html . render_posts:stories/1.html . render_archive:output/2012/index.html . render_archive:output/archive.html . render_indexes:output/index.html . render_pages:output/posts/welcome-to-nikola.html . render_pages:output/stories/about-nikola.html . render_pages:output/stories/handbook.html . render_rss:output/rss.xml . render_sources:output/stories/about-nikola.txt : : :
Nikola will print a line for every output file it generates. If we do it again, that will be much much shorter:
$ doit Parsing metadata . sitemap
That is because doit is smart enough not to generate all the pages again, unless you changed something that the page requires. So, if you change the text of a post, or its title, that post page, and all index pages where it is mentioned, will be recreated. If you change the post page template, then all the post pages will be rebuilt.
Nikola is a series of doit tasks, and you can see them by doing doit list:
$ doit list Parsing metadata deploy Deploy site. render_archive Render the post archives. render_galleries Render image galleries. render_indexes Render 10-post-per-page indexes. render_pages Build final pages from metadata and HTML fragments. render_posts Build HTML fragments from metadata and reSt. render_rss Generate RSS feeds. render_sources Publish the rst sources because why not? render_tags Render the tag pages. serve Start test server. (Usage: doit serve [-p 8000]) sitemap Generate Google sitemap.
You can make Nikola redo everythig by calling doit clean, you can make it do just a specific part of the site using task names, for example doit render_pages, and even individual files like doit render_indexes:output/index.html
The serve task is special, in that instead of generating a file it starts a web server so you can see the site you are creating:
$ doit serve -p 8080 Parsing metadata . serve Serving HTTP on 127.0.0.1 port 8080 ...
The -p 8080 tells it the port for the webserver, and is optional (the default is port 8000).
After you do this, you can point your web browser to http://localhost:8080 and you should see the sample site. This is useful as a "preview" of your work. You can combine add auto and do doit auto serve which makes doit automatically regenerate your pages as needed, and it's a live preview!
The deploy task is discussed in the Deployment section.
A post consists of two files, a metadata file (post-title.meta) and a file containing the contents written in restructured text (post-title.txt) or markdown (see the INPUT_FORMAT option in dodo.py). The default configuration expects them to be placed in posts but that can be changed (see below, the post_pages option)
You can just create them in posts or use a little helper task provided by Nikola:
$ doit new_post Parsing metadata . new_post Creating New Post ----------------- Enter title: How to Make Money Your post's metadata is at: posts/how-to-make-money.meta Your post's text is at: posts/how-to-make-money.txt
The format for the .meta file is as follows:
How to Make Money how-to-make-money 2012/04/09 13:59
The first line is the title. The second one is the pagename. Since often titles will have characters that look bad on URLs, it's generated as a "clean" version of the title. The third line is the post's date, and is set to "now".
You can add two more optional lines. A fourth line that is a list of tags separated with commas (spaces around the commas are ignored):
programming, python, fame, fortune
And a fifth line that's a URL for an original source of the post.
You can edit these files with your favourite text editor, and once you are happy with the contents, generate the pages as explained in Getting Started
The post page is generated using the post.tmpl template, which you can use to customize the output.
The place where the post will be placed by new_post is based on the post_pages configuration option:
# post_pages contains (wildcard, destination, template, use_in_feed) 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. # # if use_in_feed is True, then those posts will be added to the site's # rss feeds. # post_pages = ( ("posts/*.txt", "posts", "post.tmpl", True), ("stories/*.txt", "stories", "story.tmpl", False), )
It will use the first location that has the last parameter set to True, or the last one in the list if all of them have it set to False.
Pages are the same as posts, except that:
The default configuration expects the page's metadata and text files to be on the stories folder, but that can be changed (see post_pages option above).
You can create the page's files manually or use the helper new_page that works exactly like the new_post described above, except it will place the files in the folder that has use_in_feed set to False.
If you need a page to be available in more than one place, you can define redirections in your dodo.py:
# A list of redirection tuples, [("foo/from.html", "/bar/to.html")]. # # A HTML file will be created in output/foo/from.html that redirects # to the "/bar/to.html" URL. notice that the "from" side MUST be a # relative URL. # # If you don't need any of these, just set to  REDIRECTIONS = [("index.html", "/weblog/index.html")]
It's better if you can do these using your web server's configuration, but if you can't, this will work.
The configuration file is called dodo.py and can be used to customize a lot of what Nikola does. Its syntax is python, but if you don't know the languaje, it still should not be terribly hard to grasp.
Any files you want to be in output/ but are not generated by Nikola (for example, favicon.ico, just put it in files/. Everything there is copied into output by the copy_files task. Remember that you can't have files that collide with files Nikola generates (it will give an error).
Don't put any files manually in output/. Ever. Really. Maybe someday Nikola will just wipe output/ and then you will be sorry. So, please don't do that.
There are lots of things you can do to persoalize your website, but let's see the easy ones!
You can assume this needs to be changed:
# Data about this site BLOG_TITLE = "Demo Site" BLOG_URL = "http://nikola.googlecode.com" BLOG_EMAIL = "email@example.com" BLOG_DESCRIPTION = "This is a demo site for Nikola."
The default configuration includes a file, themes/default/assets/css/custom.css which is empty. Put your CSS there, for minimal disruption of the provided CSS files.
If you feel tempted to touch other files in assets, you probably will be better off with a custom theme.
LICENSE is a HTML snippet for things like a CC badge, or whatever you prefer.
The 'sidebar_links' option lets you define what links go in the right-hand sidebar, so you can link to important pages, or to other sites.
The SEARCH_FORM option contains the HTML code for a search form based on duckduckgo.com which should always work, but feel free to change it to something else.
Nikola doesn't really have a concept of deployment. However, if you can specify your deployment procedure as a series of commands, you can put them in the DEPLOY_COMMANDS option, and run them with doit deploy.
One caveat is that if any command has a % in it, you should double them.
Here is an example, from my own site's deployment script:
DEPLOY_COMMANDS = [ 'rsync -rav --delete output/* firstname.lastname@example.org:/srv/www/lateral', 'rdiff-backup output ~/bartleblog-backup', "links -dump 'http://www.twingly.com/ping2?url=lateral.netmanagers.com.ar'", 'rsync -rav ~/bartleblog-backup/* email@example.com:bartleblog-backup', ]
Other interesting ideas are using git as a deployment mechanism (or any other VCS for that matter), using lftp mirror or unison, or dropbox, or Ubuntu One. Any way you can think of to copy files from one place to another is good enough.
To create an image gallery, all you have to do is add a folder inside galleries, and put images there. Nikola will take care of creating thumbnails, index page, etc.
If you click on images on a gallery, you should see a bigger image, thanks to the excellent colorbox
The gallery pages are generated using the gallery.tmpl template, and you can customize it there (you could switch to another lightbox instead of colorbox, change its settings, change the layout, etc.).
The dodo.py options affecting gallery pages are these:
# Galleries are folders in galleries/ # Final location of galleries will be output / GALLERY_PATH / gallery_name GALLERY_PATH = "galleries" THUMBNAIL_SIZE = 180
If you add a file in galleries/gallery_name/index.txt its contents will be converted to HTML and inserted above the images in the gallery page.
Nikola is released under the GPL version 3 which is a free software license. Some components shipped along with Nikola, or required by it are released under other licenses.
If you are not familiar with free software licensing: In general, you should be able to do pretty much anything you want, unless you modify Nikola. If you modify it, and share it with someone else, that someone else should get all your modifications under the same license you got it.