Deer and Hawk

Deer and Hawk

Adventures in curiosity

Introducing a Static Site Blog with Pelican

I started this blog on WordPress. After testing it out I realized that WordPress is overkill and all the WordPress hosting options and backups and security configurations were going to cost a small fortune. I also found all the WordPress features just got in the say of doing some really simple things. It has all the bells and whistles and too many buttons to push.

A few years ago I had played around with static site generators. A static site generator doesn’t use a database and complex server technology like WordPress. They are good for simple sites that are a few pages, a feed of posts and some categories and tags. In goes content as plain text files that you can edit with any editor and out comes a bunch of plain HTML files you can put anywhere. You can host a static site for super cheap (and even free) on any basic server.

There are many static site generators.

I settled on Pelican because it is in my favorite programming language, Python. I revisited Pelican and I was impressed with the new version. This post will be a simple introduction to site generators and some tips for using Pelican that may apply to other generators. There are tons of great articles on Pelican and site generators in general, but if you are static site generator “curious” this might be a good starting point.

What You’ll Need

Setting Up Pelican

Pelican has a great quick start introduction.

Once you have Pelican installed (I highly recommend using a virtual environment in Python to manage all the packages and to make upgrading Pelican later easier) then you can create a basic site with the default template just by running:

pelican-quickstart

This will set up a site outline where you can put content in /content for blog posts and /content/pages for static pages. The generated site files will be put in the /output directory.

You do this by running:

pelican content

I won’t rehash all the options here. What I will point out are some things I had to figure out on my own.

You’ll want a theme

Pelican supports “themes” or different looks and feels for your site. There are some examples on the Pelican Themes site.

Out of the box, Pelican will generate a servicable site with a few configuration options.

To change the look of your site, you can choose a pre-built theme or build your own.

To choose a pre-built theme, you install it with the pelican-themes command.

Then you can simply set the name of an installed theme in your pelicanconf.py file.

THEME = “/path/to/theme”

But building your own is surprisingly simple.

I was interested in using an out of the box style sheet so this was perfect. I didn’t want to do a bunch of custom styling.

Adding some style

Next I looked around for some helpful starter style sheets for making my site look more than “simple”. I found Pico, which is a “semantic HTML” style sheet. I like the clean design and even the default styles are pretty attractive. The default things like spacing between elements is a nice balance of compact and readable.

If your site uses semantic HTML (e.g. it tags things as what they are instead of using generic tags like a <div> for everything) then Pico requires almost no work to style your site. Fortunately for us, the simple theme uses semantic markup, e.g. it uses <header> for the top of the page, <article> for blog posts and <footer> for the bottom of the page.

I just picked the Pico color scheme I liked. Pico provides a “classless” version of the stylesheet so you don’t even have to add classes to all your HTML. It just uses the type of HTML element to style it. No markup needed. Then I edited the base.html file in the templates directory and copyied the CSS file into the /css directory.

I added the link to the Pico stylesheet in the <head> element of base.html:

<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/theme/css/pico.classless.cyan.css" />

That’s it. I created a whole new theme by editing one file and adding one file.

Granted this site is not fancy but it is (a) clean and readable and (b) really easy to update and maintain. I think default Pico is a great choice for a starter look and feel.

If I want to get fancier, I can customize Pico a bit or edit the theme templates to add more features.

You’ll want to add some structure

By default, Pelican converts Markdown or restructuredText or HTML pages in the /content directory to the static site (in /output). You can add a /content/pages directory if you want to add some static pages to your site.

But this doesn’t support a typical workflow for me, like generating ideas, editing drafts, and publishing content. It isn’t easy to see what is in draft or what is published already.

So you can add a drafts folder, and ideas folder etc. to the content folder. So if you want to keep your published content in a separate folder you can do that.

Just be sure to add the new source paths to pelicanconf.py. For example:

ARTICLE_PATHS = ['published', 'drafts']

For now, I am actually using a built in feature of Pelican. If you add a Status: drafts line to the top of your article file it won’t publish it but it will include it in a /drafts folder so you can share links for review, etc. Note Status: hidden will publish it to the site but will not add any links to it from the rest of the site. Adding Status: published will do the expected thing.

If I get fancy, I might use more subfolders. But I think it complicates editing the Markdown if I want to use my editor’s ability to link between files and I want the generated files to link to each other. For example, if I had a file in the drafts folder and I wanted my editor to link to a file in the published folder, then when I publish the draft article I would need to update my links. Pelican does support a link syntax for static file links between posts and static assets, like attached files and images. However, if I use that non-standard Markdown syntax my Markdown editor will not understand the links and previews will not work!

Publish

If you used the pelican-quickstart set up, then when your content is ready, you should probably change some default settings you used for development.

These are found in publishconf.py, which inherits all the settings from pelicanconf.py.

The main things to change are SITEURL and RELATIVE_URLS. You’ll want the latter set to False so the generated site has all the links pointing the SITEURL.

Then, to generate a site ready to publish you can run:

pelican content -s publishconf.py

To really publish to the web, you’ll need to have hosting set up, probably connected to some sort of repository online or available via FTP.

Conclusion

Setting up and using Pelican is more technical than using WordPress. But WordPress is bloated with features! It is a full-blown Content Management System, and doing some basic stuff seems over complicated. I just wanted to edit some files and publish them online. Now that I have Pelican configured, I can do that with a few simple commands.

It is also nice to have a complete copy of my site in one place on my computer instead of on someone else’s system in a database somewhere. I can tweak it, move it somewhere else, even work completely offline. And it is in a very portable format. Because the content for my blog is just plain text files I am not locked into any system or publishing platform.

I’ll write a future blog post about how to publish a static site to a hosting provider. There are tons of web hosting companies but not all have a basic static site tier. I tried both kinsta.com and AWS and ultimately went with AWS Amplify Hosting even though it is more complicated to set up than Kinsta.

Good Luck!