ramoska blog logo showing grasshoper

ramoska

Create blog site with Pelican

Posted on November 2023 in Web development

Creating site

First things first - I need to install Pelican. I am going to use pipx for that, mostly because it installs packages in their own virtual environments and makes these applications available in shell (adds them to PATH). Since I tried to revive my old blog to no avail (because misremembering Nikola as Pelican), I just go with pelican-quickstart and answer prompt questions to make it closest to what it used to be. Since I opted to generate tasks.py and Makefile, it also created tasks.py for invoke library to use. Since Makefile is sufficient for me and I don't want to use invoke I'm just deleting tasks.py. Quickstart command also created two config files: pelicanconf.py and publishconf.py. Looking into filenames I assume that config from publishconf.py overrides pelicanconf.py when I run make publish.

Config

Pelican came with 2 themes after installing it: simple and notmyidea. Both of them didn't look anywhere close to what I had built before so I had to start with downloading custom theme. Thankfully it was quite easy to find one that resembled my old blog layout-wise. Just go to Pelican themes page, look over previews for themes they provide and follow their instructions (or copy theme source files to your themes directory). I chose Flex theme. I intend to recreate my old theme from Nikola theme I used to use, but for now I have more pressing matters like deploying this blog somewhere. Default configuration looks pretty good, nothing to change there for now. From official docs it looks quite modifiable, but from config itself it looks like a lot of sane defaults are used, so YAY! for me. I also like approach of overriding dev configs with publishing ones, so both local and production sites should be as similar as possible.

What I want to change from defaults and what I like in Nikola is to have article slug to be folder name containing index.html file. This way I can have nice URLs like /setup-pelican-for-blog/ instead of /setup-pelican-for-blog.html. It just looks cleaner to me. Also on the same go let's enable yearly archives. Just a few lines in config and we're good to go.

ARTICLE_URL = '{date:%Y}/{slug}/'
ARTICLE_SAVE_AS = '{date:%Y}/{slug}/index.html'
ARTICLE_LANG_URL = '{date:%Y}/{slug}/{lang}.html'
ARTICLE_LANG_SAVE_AS = '{date:%Y}/{slug}/{lang}.html'
PAGE_URL = 'pages/{slug}/'
PAGE_SAVE_AS = 'pages/{slug}/index.html'
PAGE_LANG_URL = 'pages/{slug}/{lang}.html'
PAGE_LANG_SAVE_AS = 'pages/{slug}/{lang}.html'
YEAR_ARCHIVE_SAVE_AS = '{date:%Y}/index.html'
YEAR_ARCHIVE_URL = '{date:%Y}/'

ARCHIVES_SAVE_AS = 'archives/index.html'
AUTHORS_SAVE_AS = 'authors/index.html'
AUTHOR_SAVE_AS = 'authors/{slug}/index.html'
AUTHOR_URL = 'authors/{slug}/'
CATEGORIES_SAVE_AS = 'categories/index.html'
CATEGORY_SAVE_AS = 'categories/{slug}/index.html'
CATEGORY_URL = 'categories/{slug}/'
TAGS_SAVE_AS = 'tags/index.html'
TAG_SAVE_AS = 'tags/{slug}/index.html'
TAG_URL = 'tags/{slug}/'

DEFAULT_DATE_FORMAT = '%Y %B %d %H:%M'

Included language settings just in case, although I doubt I will be writing in any other language than English. And yeah, I'm European, so 24h format is the default one. Also sticking to yearly only archives because let's be honest - I don't think I will be writing that often, especially with kids around.

That looks about right for now. Next things will be to rework theme from Nikola times. It seems like nice opportunity to look into Tailwind and see what all the hype is about. At least front-end engineers from my bubble are pretty excited about it. And also not to forget about deploying this blog somewhere - most likely on DigitalOcean. Or maybe GitHub Pages.

Writing content

This one is pretty straightforward. On Nikola I used to write posts in .rst and I keen to keep it that way. It might sound weird, but ReStructuredText for me at least is easier to write than Markdown. Be it inserting links, formatting paragraphs, adding metadata - it just feels more natural. Nonetheless, main focus is on content, not on markup language. Posts need some metadata to be set:

:author: ramoska
:date: 2023-11-11 23:00
:modified: 2023-11-11 23:00
:tags: pelican, python, blogging
:slug: setup-pelican-for-blog
:category: blog
:summary: With this post I will be setting up Pelican for the first time for
  blogging. I want to see how templating is working and how sites are built,
  how paths are defined, and how easy it is to tweak it to my liking.

That's what this post has. I'm not sure if I like summary field. This one is used for description meta tag in HTML and in preview on index page. For meta tag it kind of works, but I really like how Nikola handles showing let's say first paragraph with .. TEASER_END directive - it was super easy to set where to cut off post for index and I didn't have to rewrite same paragraph twice. Maybe if I ever have time I'll look into this in more details. But on the other hand it kind of makes sense to have separate summary displayed on index page and not axed version of post itself. I guess it just makes me work with tool I have and not against it. With Nikola I would have first paragraph phrased in different way for it to be more like a summary. And with Pelican I can just write summary and don't think how my entry would fit into index page.

Linking to other pages inside site is also pretty straightforward, nothing fancy necessary for Pelican to pick it up: {filename}/path/to/file.rst and that's all. And this snippet is used below to include image (or any other static content for that matter):

.. image:: {static}/images/built-site.png
  :alt: Output of tree command showing static site structure
  :width: 50%

Site structure is also pretty simple. There is root directory, which contains all posts, then there's pages directory, which contains all pages, which are a bit different concept from posts/articles - pages are more like static content (think about About page, or Contact page). That's how it works out of the box. But if it's not enough, every article (Pelican uses that concept instead of blog) can have save_as and url fields set, which will in essence override default behaviour how article is saved and how it's URL looks, giving way to more complex site structure. It also allows to set different template for each article/page. I would say it's pretty flexible to build any static site.

Build site

Building site is as easy as running make publish and it will build something like this:

Output of tree command showing static site structure

I could go with less directories if that were my aim, but as I mentioned earlier I want to have pretty URLs. Now it's up to me to put all that static content to my hosting provider of choice and it's done. Everything looks very simple and easy to use. I'm pretty happy with Pelican so far. Now let's go to check what Writerside is all about.

This is part 2 of the Resurrecting blog series.

Previous post:
Stick to Pelican or switch to Writerside
Next posts:
Create site with Writerside
Setup blog deployments

Tags: Pelican, Python, Blogging