There are different methods to construct a website, for example you can develop quite complex webs on a web server. I attempt to learn Django before but dump it quite soon after some hours reading of the documentation. The reason is simple - I feel its capability is much beyond my requirement for a simple blog and I seriously concern the time I would spend on learning it. Later I learned another term called static website generator. It seems that I can concentrate on my writing and let the generator do all the complex work related to website. There are lots of choices for the static website generators but two of them draw more attention from me. One of them is Jekyll, which is also the engine powering GitHub Pages. I also notice some excellent integration with org-mode and introductions. The downside is its written in Ruby which scares me a bit since I am not ready to learn another language (although it may not require too much understanding of Ruby in reality). After a bit more search work I finally found my choice - Pelican. It is written in Python which makes me feel more relax since I am learning Python currently. And it firms my stand more after I read the quickstart of its documentation and create a simple website. Besides, I love pelican the bird!

When I was hesitating to choose Markdown or reStructuredText format to write the content, I started to wonder if I can use org-mode as org file is also plain text and can be extracted as html. It turns it is possible to integrate org-mode and Pelican and there are already excellent useful codes written by others to help the integration. In the following posts I will describe a comprehensive yet simple enough procedure to setup a Blog which can be handed in hours (I did not contribute anything to the tools or codes involved, at least not now)

Pelican setup

During the setting up for my blog website, I browsed several websites to acquire information. There are two sites among those I found particular useful, i.e. the quickstart section of Pelican’s official documentation and a screencast from Justin Mayer. The full official documentation would be the best place to look if you need any further information. So let us get started to set up Pelican for a website first.

Install Pelican

It is better to create a virtual environment for Pelican through virtualenv and then install Pelican related packages in the virtual environment. The following commands creates a Pelican virtualenv and activates it:

1
2
3
virtualenv ~/VirtualEnvs/Pelican
cd ~/VirtualEnvs/Pelican
source bin/activate

Then install Pelican and several useful packages through pip:

1
pip install pelican markdown typogrify

Create a project for your website

In this section we first create a folder for the Pelican project and then use pelican-quickstart command to generate the project. Don’t worry too much about the questions asked by this command if you are not sure for some of them, as you can always modify those parameters in a later stage.

1
2
3
mkdir ~/Projects/fanpengblog
cd ~/Projects/fanpengblog
pelican quickstart

After above steps you should get a hierarchy similar to the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Directory structure of Pelican project
/Users/xiaok/Projects/fanpengblog/
├── Makefile
├── content
├── develop_server.sh
├── fabfile.py
├── output
├── pelicanconf.py
└── publishconf.py

2 directories, 5 files

Write the content for your website

Now we can write our first website page and store it under the content directory. There are several languages options can be used here, i.e. reStructuredText, Markdown or direct html. As later we are going to use org-mode to write these contents, we choose Markdown format temporarily for simplicity. Change to the content directory and create a Markdown file and write some words there.

1
2
cd ~/Projects/fanpengblog/content
emacs firstblog.md
1
2
3
4
5
6
Title: My first blog
Date: 2015-10-04 12:00
Category: Tools
Tags: pelican org mode

Hello, this is my first blog post!

Preview your website in localhost

Two different methods can be used to generate and preview the website after creating the source file of our first webpage.

invoke Pelican command directly

1
2
3
pelican content
cd ~/Projects/fanpengblog/output
python -m pelican.server

The pelican content command generates html file in the output directory corresponding to those in the content directory. The pelican.server script in output launches Pelican’s web server and you can preview your site in the browser by typing http://localhost:8000/ in the URL field.

use Makefile to run Pelican command automatically

After the execution of pelican-quickstart command, a Makefile is also created. Simply run make html will generate the website while make serve will launch a local server.

1
2
make html
make serve

Until now we are able to wirte simple blog post with the above infomation. Of cource we can do more advanced operations like include figures, link to other webpages .etc. Please feel free if you prefer to stick to use Pelican excusively with your favourate language to write contents in the content folder. But I am eager to learn some knowledge about org-mode, so I will integrate org-mode with Pellican in the next post.

Integrate with org-mode

org file can be exported to html format through C-c C-e h command, so it’s straightforward to think that I can write my blog posts in org-mode and then export them to html files. If these html files are put in the content directory in the Pelican project, the Pelican command then can generate the static website with these source files. However it may need some settings for the export command in org-mode to meet the requirement format of html files by Pelican. Fortunately some people already did the great work! Basically all of the following work come from Noah Hoffman and I just figured out how he make it work and modify it a bit to my taste.

batch export of org-mode files from command line org-export

org-export is a elisp package which can do batch export of org-mode files from the command line. There is even a pelican option. The first step is to clone it to my local directory. In order to make the org-export command available in shell, I need to put it under one of the directories in my $PATH. Or I can just put it under the root of my Pelican project and use the absolute path to org-export.

Then it’s time to create some org file for my posts. Its better to create a separate under the Pelican project to store all the org files together. In order to use the SConstruct file in the next section, I name this org file folder as org-content. So now the directory tree in my blog project looks like following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Directory structure of Pelican project
/Users/xiaok/Projects/fanpengblog/
├── Makefile
├── content
├── develop_server.sh
├── fabfile.py
├── org-content
├── org-export
├── output
├── pelicanconf.py
└── publishconf.py

4 directories, 5 files

Now I can create an org file secondpost.org in the org-cotent folder and write following content in the org file:

1
2
3
4
5
6
#+TITLE: Second Post
#+DATE: 2015-10-14
#+CATEGORY: Tools
#+PROPERTY: TAGS pelican, org mode

This is my second post and it is written in *org-mode*!

Note how we add the CATEGORY and TAGS key words as required by Pelican. Next change to the org-export directory and run the following command to convert the org file to html file:

1
./org-export pelican --infile org-content/secondblog.org --outfile content/secondblog.html

Finally I can use the Pelican command or the Makefile to generate the website and preview it in localhost.

Automatically build with scons

It would be very boring to invoke the org-export command for each org file and specify the input and output directory. I guess it will be a piece of cake to integrate auto org-export all the org files in org-content folder to content folder in the original Makefile provided by pelican. But since I am following Noah’s work, I am going to use his scons method rather than add additional functionality to the Makefile. scons is an auto build tool like make or cmake but wrote in Python. Further more it provides access to all the Python functions. So I use following command to install scons:

1
brew install scons

Then I copy the SConstruct file and bin folder from Noah’s repository to my Pelican project. The SConstruct file do the following thins:

  • Convert org files in org-content directory to html files with same basename in content directory.
  • Run pelican content command to generate the website in output folder.

Now the work flow would be like this:

  1. Write blog post in org file under org-content directory.
  2. Use scons in shell to execute SConstruct file (of course in the directory of my Pelican project so it can find SConstruct just like make can find Makefile)
  3. run make serve to preview the website in localhost.
Note 1
it’s possible to implement the functionality of SConstruct file in Makefile and vice versa, if I know a bit more about scons or make -_-
Note 2
I replace the code for appending path in Enviroment in the SConstruct file to make it more compact.

Delete following part in SConstruct file:

1
2
3
4
paths = ['org-export',
         path.join(environ['VIRTUAL_ENV'], 'bin'),
         '/usr/local/bin', '/usr/local/sbin', '/usr/bin', '/bin',
         '/usr/sbin', '/sbin', '/opt/X11/bin', '/usr/texbin']

Then add following part in SConstruct file:

1
2
3
env = Environment(ENV=environ,
                  variables=vars)
env.PrependENVPath('PATH', 'org-export')

Host website on Amazon S3

To host my website on Amazon S3, I basically followed instruction from this blog. Amazon Web Services (AWS) provides a cloud storage service called S3, where I can upload my static website content to. I also registered my website domain from AWS and use its DNS service Route 53 to point the domain to my website content on my Amazon S3 content.