I just finished converting this blog to Pelican, a static site generator built entirely on Python. The conversion process was so easy, and Pelican is such a pleasure to work with, that I wish I had done this much sooner instead of letting this blog languish for over a year and a half.
To reboot the blog and kick things off again, I'll describe just how easy it was to convert to Pelican, compare it to what I was working with before, and lay out some ideas for the future.
Starting with Pelican
So Pelican is a static site generator, which means it builds a complete website from a template and a bunch of files representing content. The content is usually written in a plain text markup language like Markdown. Pelican has explicit support for common blog features like articles, pages, categories, comments, and syndication. The blog was already written in Markdown and built using a static site generator, and I wanted to try redoing it with Pelican.
Creating a Pelican site is simple, just run
in some content, and run
pelican to compile it. I only had to copy in
the existing Markdown content and massage the metadata headers into
Pelican's format. I also wanted to preserve the URL scheme I had already
been using, and found that it was trivial to tweak the default config
files to do exactly that. The result was a new site that mostly
replicated the content and URLs of the existing blog.
I noticed a small difference in the rules that Pelican uses for transforming a page title into a URL. There is one post that contains a "+" plus sign. My previous blog software converted this into the word "plus", while Pelican drops it by default. Fortunately, it's simple to add custom URL transformation rules, and I got this post where it needed to be. If generic transformation rules don't work, Pelican also allows an article to specify exactly what its URL should be in its metadata.
I also wanted to be able to add a delimiter in articles to mark the beginning of the article as a summary. By default, Pelican pulls out the first 50 words as the summary, probably cutting off in mid-sentence. I wanted more control, without having to duplicate the summary in a header field. Fortunately, there's a plugin for that. The pelican-plugins repository has dozens of plugins, including one that recognizes a delimiter comment marking the end of the page summary.
At this point, setting aside appearance, the old blog was converted perfectly, preserving all of the content, URLs, summaries, feeds, tags, and comments. I had wanted to know if I could use Pelican to publish my blog, and in about an hour I had answered that easily, and it was basically ready to use. Of course the next question was, what else can I do?
I'll take a small detour here and try to explain why I did this conversion in the first place.
When I started this blog three years ago, I wanted to use a static site generator. I settled on Octopress at the time because it seemed simple and included all of the features I wanted. Octopress is based on Jekyll, which was and is probably the most popular static site generator. Octopress looked like Jekyll with a bunch of integrated plugins and theming problems already solved. It looked like a quick way to get started with Jekyll without having to learn Ruby and mess around with CSS, just write and publish. And yes, it was pretty easy.
One problem that was quickly apparent is that Octopress was basically a preconfigured Jekyll project. To customize Octopress for your own blog, you essentially have to fork Octopress and make changes to it. There was no way to run upstream Octopress against your own configuration and content.
Another problem that's a direct corollary, Octopress is based on a now-ancient version of Jekyll. It's impossible to take advantage of any Jekyll improvements over the years because Octopress used Jekyll 0.12 from 2012. If Octopress updates to a newer version, the only way to take advantage would be to rebase your local fork onto Octopress upstream changes and hope for the best.
Not only are configuration changes made in the Octopress repository itself, but content is put there by default. So a typical Octopress blog is a fork of the Octopress project, with local config files, and with all articles and pages mixed in there too. I actually created a subrepo for just the content, to try to maintain the content separately from the Octopress repo. This seemed better at first, but I still had config changes in one repo and content in the other, and they're not exactly independent. Add in a customized fork of a theme, and that's three separate repositories to maintain one simple blog.
I saw that Octopress had been working on a redesign to fix these problems and work with the latest Jekyll, but it seems like development has stalled. Maybe Jekyll is good enough now that Octopress isn't really needed anymore? Maybe the authors moved on and the Octopress community dissolved? Whatever the state of the project, I had a blog built with a tool that was cumbersome to maintain, wasn't being updated, and I didn't really understand. I stopped updating my blog due to a confluence of many life events, and being difficult to maintain wasn't helping.
I was at PyCon 2017 last week, and one of the strongest messages that I took with me was to try to find a Pythonic way to do everything. Since Python can do so many things and make them so easy, why not do more things in Python? I made a note to find and try out a best-practices Pythonic static site generator to reboot my blog, and I found Pelican. And here we are.
Pelican feels extremely Pythonic to me, because it made it extremely easy to build a replacement blog from scratch using sane defaults and working with my existing Markdown. The default behavior is easy and intuitive and makes something that just works. Now, beyond using the defaults, customizing Pelican is done with Python modules, and there is an active community building reusable plugins and themes for Pelican.
To add plugins and choose a theme, I only needed to point at the pelican-plugins and pelican-themes repositories and add a little configuration. Most of the themes are listed with screenshots and live demos at pelicanthemes.com. I was very happy to find the pelican-bootstrap3 theme because it is clean and minimal, it's based on the widely used Bootstrap framework, and it is extremely customizable. With just a little exploration of the config space, I now have something that behaves and looks more like I wanted the original blog to and less like the Pelican default theme.
I had to stop myself from customizing too much, write this post, and update this blog after a long hiatus. It's functional and pretty much does what I want for now, but there is still more customization to be done. I would like to install a favicon. I want to get the built-in site search feature working. I would like to look at the Bootswatch themes for Bootstrap that can easily be dropped into this theme. I might add a tag cloud once I have some more content.
For now the most important thing is that the blog is up and running again. I hope the switch to Pelican will lower the barrier to updating a bit and help keep things moving. Sometimes the right tools make the difference. I'm also curious what else Pelican can be used for. Are there any downsides that I haven't run into yet? Other Pythonic tools for compiling content into web sites, documents, presentations?