The last trend for blogging is to use a static site generator. This has some advantages over dynamic websites (wordpress) and online blog services (blogger):
- This is more easy to do than deploying a application server, as there is no special installation/configuration needed (especially if you use GitHub for hosting).
- This prevents attacks on the server as there are no interactions with dynamic parts.
- The posts and associated contents can be versioned in a git repository as it is using only text files, not databases.
- The content of your blog is not locked to an online blog engine, so you are free to move easily whenever you want all your content to a new system.
Thanks to Spacemacs, I entered the Emacs' world recently and started to enjoy
org-mode. When I decided (again) to start a blog, I looked around for a static
site generation supporting this file format. The problem of
org-mode is that
it is only fully supported within emacs, as most of its power come from all the
extensions that will probably not be supported by any parser. I looked at
different static site generators, among which only a few where supporting more
than Markdown/RestrucuredText. My choice was directed to Nikola which has a
support of a lot of format thanks to
pandoc. But I was pleasantly surprised
when I read the description of the
orgmode plugin for Nikola:
This plugin implements an Emacs Org-mode based compiler for Nikola.
If your emacs does not ship with org-mode (>=8.x), you will have to edit the init.el file supplied with this plugin, and load a newer version of org-mode.
This meant that the plugin is using the real Emacs
org-mode to render the
posts of the website. This finished to convinced me starting my blog using this
engine, and to write about this experience (in
org-mode of course) as a first
post. You are reading it. In this article I will detail the installation
procedure to setup a website powered by Nikola and hosted on GitHub pages.
Setting up the system
This first part will describe how to set up the whole system, from GitHub pages
GitHub is offering a service called GitHub pages that allows people to serve
static websites through their GitHub repositories. There is the possibility to
serve one website per repository and also to create one website linked to the
username. Thanks to this, people can own their associate their blog with their
GitHub's usernames. One restriction being that GitHub is only serving static
.html pages with some
css, but this should be
far enough for running most personal blogs.
The main user website is be accessible at
website will be served from the
master branch of a repository that should be
<username>.github.io. You can have a look at the GitHub's documentation
for more details about this.
The first step to install the blog is to go on GitHub, and create a repository
<username>.github.io. You can give a description if you want, but don't
check the "Initialize this repository" checkbox, nor add a
.gitignore or a
license: we want the repository to be empty. Once the repository has been
created, you can clone it on your computer with:
$ git clone email@example.com:<username>.github.io.git ~/blog
master branch will be used for the rendered website, let us create a
sources to put the… sources of your blog:
$ cd ~/blog $ git checkout -b sources
You can already add a
.gitignore to the folder:
*.py[cod] __pycache__ cache output .doit.db _env/
and commit it (be sure to be on the
$ git add .gitignore $ git commit -m "Add .gitignore"
We should be ready to continue.
There are different ways of installing Nikola:
- You can install it from your package manager, if your distribution provides a package for it. This is the best solution if the package exists.
- You can install it globally on your computer with
pip, but this has the tendency to "pollute" the filesystem, as it is not managed by the package manager.
- You can install it within a Python virtual environment. This is the method I will present you here.
- If you have your own preferred way to install it, please do so.
I choose to use a virtual environment because Archlinux is not providing an
official package for Nikola. There is an
AUR package for it, but this implies
to build several of its dependencies from
AUR too, and I don't went to spend
my time checking their
PKGBUILD at each update. As I also don't like using
pip (or alternative tools) to install globally on my system, I decided to use
a virtual environment.
pyvenv virtual environment is provided directly by the
python package on
Archlinux, so I decided to go for it. You can of course use another virtual
environment tool if you prefer. In order to make the installation of Nikola in a
virtual environment the simplest as possible, I created a simple Makefile that
will do the most of the job.
Let us start by defining a variable for the name of the environment folder:
ENVIRONMENT := _env/
I also added a default target as first one in the Makefile to select what should be called when no target is specified. It is a good practice from my point of view, as it uncouples the logic from the target ordering.
Then a target to create and clean the environment:
$(ENVIRONMENT): pyvenv "$@" clean: rm -rf "$(ENVIRONMENT)"
If you are not used to Makefiles, it can look a little bit complicated. As we
are using a variable, the target name is replaced by its value, same for
that is a special variable that as for value the target's name. So it translates
_env/: pyvenv "_env/" clean: nikola clean rm -rf "_env/"
In order to use a virtual environment, one as to manually source from his
$(ENVIRONMENT)/bin/activate file. Once the environment has been
activated, the user need to install Nikola. To make this simpler for the user, I
have done a
setup target printing all required commands:
setup: @echo "make $(ENVIRONMENT);" @echo "source $(ENVIRONMENT)bin/activate;" @echo "pip install --upgrade pip 'Nikola[extras]';"
When this target is executed, it will only print this to the command line:
make _env/; source _env/bin/activate; pip install --upgrade pip 'Nikola[extras]';
This contains all steps required to setup the system:
- Call the Makefile to create the environment
- Source the
activatefile to enable it
pipwithin the environment to upgrade
pipand install/upgrade Nikola
Instead of asking the user to copy/paste this in their terminal, it is possible to evaluate it directly with:
$ eval $(make setup)
This will do all the work, but let us add an
help target that explains this
literally to the user:
help: @echo "To setup Nikola environment, please use 'eval \$$(make setup)'."
You can now initialize the environment and install Nikola with:
$ eval $(make setup)
It will takes time the first call, but later ones will be much faster. Try to
nikola -h to be sure everything was installed correctly. The resulting
Makefile can be found on my GitHub repository.
The skeleton of the website can be created with these commands. Note you will have to give some information to create the site:
$ nikola init my_first_site # Fill the asked information $ mv my_first_site/* . $ rm -r my_first_site
Nikola will create the site in a sub-directory so we have to move it to our
current directory. You will see that for now there is only empty folders and a
conf.py file. It is a pretty long configuration file, but you have to go
through it if you want to see all possibilities to customize Nikola.
You can now commit the
Makefile and the
conf.py files in the
branch (if not already done):
$ git add Makefile conf.py $ git commit -m "Add Makefile and conf.py"
Here comes the interesting parts: making Nikola play with org-mode! There is an "official" Nikola's plugin for this, so is quite simple to install:
$ nikola plugin -i orgmode
The prerequisite being to have Emacs installed with
org-mode > 8.x.
You will also have to edit the
conf.py file so that Nikola will recognize the
org files. For this, edit the file and add the following lines:
# Add the orgmode compiler to your COMPILERS dict. COMPILERS["orgmode"] = ('.org',) # Add org files to your POSTS, PAGES POSTS = POSTS + (("posts/*.org", "posts", "post.tmpl"),) PAGES = PAGES + (("stories/*.org", "stories", "story.tmpl"),)
You can commit the added files:
$ git add plugins/orgmode conf.py $ git commit -m "Add org-mode support"
Testing the system
Everything should be set up now. In order to test it, you can use the following commands:
$ nikola build $ nikola serve
And open your browser at http://localhost:8000. If you have a web page, it is
working, congratulations. The server can be stopped by pressing
Now that the system is set up correctly, let's start blogging.
To write a new post, simply use the following command:
$ nikola new_post -e -f orgmode
-e flag tell Nikola to open the file directly for editing, and the
orgmode tell it to use the
org-mode format. Then simply save the file and
close your editor when this has been done.
Building the website
As we already saw previously, the site can be built and tested with the following commands:
$ nikola build $ nikola serve
build command create the static content of the site, and the
command run a development server to see what it looks like locally. This can be
done whenever you want to see the changes. Note there is also this command that
can be used advantageously as it will detect changes and rebuild the site
$ nikola auto
Deploying on GitHub
In order to deploy on GitHub easily, only one simple step has to be done: edit
conf.py file and change these variables as in this snippet:
GITHUB_SOURCE_BRANCH = 'sources' GITHUB_DEPLOY_BRANCH = 'master'
It is all. Now you can deploy your website on GitHub by simply calling:
$ nikola github_deploy
Go to your
http(s)://<username>.github.io/, your website should be there :-)
Separate metadata from posts
It is possible to extract the metadata out of the posts files. For this simply
change this variable in the
ONE_FILE_POSTS = False
The theme of the website can be changed easily. Nikola provides some predefined themes that you can easily use. For this use the following command:
$ nikola install_theme <theme_name>
And change the following variable in the `conf.py` file:
THEME = "<theme_name>"
Some theme requires more configurations, read the information provided on their pages.
Code syntax coloration with org-mode
pygmentize tool is needed in order to have syntactic coloration with
org-mode. It should have been installed within the virtual environment
already, so no step should be needed.
You need to generate a custom
css file in order to make the coloration being
displayed on the
html page. For this run the following commands:
$ mkdir -p files/assets/css/ $ pygmentize -S friendly -a .highlight -f html >> files/assets/css/custom.css
Then rebuild the website: the source codes should be highlighted now!
$ nikola build $ nikola serve
It was a really interesting work to setup this project. Nikola is a simple and
nice static site generator, and it is plugin for working with
org-mode is the
better that I have seen.
I should mention that I have not tested the
org-mode really far, so there may
be some surprises. For now the only problem that I have seen is the inner links:
I did not find a way to make it work for inserting a table of contents. Also,
including images work, but for an unknown reason I have to set links to one
level above, i.e.
../../images/logo.png instead of
this are relatively minor problems, and having a tool offering
Markdown, RestructuredText, and many other format is a nice to have.
- Website sources: GitHub