Julian Mehne

Switching blog engines

python, website

I switched from Hugo to pelican. Which doesn't make super much sense, I guess, from a technical perspective. But, this is my personal website and I wanted to make it completely my own. I could never muster up the energy to dive into Hugo and how to make my own theme. The theme I was using used techniques I didn't understand, so it felt hard to modify it. Somehow, pelican seems more simplistic and approachable to me personally and I don't have crazy expectations that I need to "scale" this page.

The rest of this article assumes you want to use pelican with your own theme and that you use markdown for your pages.

Getting started

The official docs are handy as a reference. Because we are in 2024 (let's see how this will age), install pelican with pipx:

pipx install pelican[markdown]
pipx installs a virtual environment to ~/.local/share/pipx/venvs/pelican and this is a good time to add any extensions we want:
pipx inject pelican pymdown-extensions
By default, pelican uses Python-Markdown to render Markdown files and the pymdown-extensions package contains additional syntax extensions. We now have the pelican CLI command available. Let's get started:

mkdir my_project
cd my_roject
pelican-quickstart

We should now have a basic setup. Let's enable some markdown extensions in the pelicanconf.py file:

MARKDOWN = {
    "extensions": [
        # Table of contents with [TOC]: https://python-markdown.github.io/extensions/toc/
        "toc",
    ],
    'extension_configs': {
        'markdown.extensions.codehilite': {'css_class': 'highlight'},
        'markdown.extensions.extra': {},
        'markdown.extensions.meta': {},
        # Code blocks in lists etc.
        # https://facelessuser.github.io/pymdown-extensions/extensions/superfences/
        "pymdownx.superfences": {"disable_indented_code_blocks": True},
    },
    'output_format': 'html5',
}

Let's take a look at our pages and automatically re-generate them whenver we do changes:

pelican --autoreload --listen
Access the webpage on localhost:8000 from your browser.

!!!! Download simple scheme !!!

Pelican in a nutshell

Pelican uses generators to ... generate ... content. There are two main types:

Beyond rendering the articles, pelican uses them to create:

For the content collection pages, pagination can also be activated such that instead of listing all available items, it only lists n items and a link to the next page.

A pelican theme uses jinja2 templates to render these pages and the required templates correspond to the list above. base.html is used for all generated pages and most templates extend it. It contains the header (usually a title and the naviagation/menu bar) and footer. We have (-> means 'extend', <- means 'imports'/'includes'):

Customizing the site

Static landing page

Use one of the following:

Using a normal post

Create a post and save it to index.html.

---
title: Welcome!
save_as: index.html
status: hidden
---

Hello, world!

You can also use an HTML page instead, see the docs or my own page. We still want the page of blog posts which used to be written to index.html, so edit pelicanconf.py:

INDEX_SAVE_AS = "posts.html"
MENUITEMS = [
    ("posts", "posts.html"),
]

Using a template page

For a more complicated page you may want to use a separate jinja2 HTML template. This can then be processed by pelican and the whole context is available to the template. pelicanconf.py:

TEMPLATE_PAGES = {
    # Processes pages/home.html with jinja (so the context is available) and saves to index.html
    "pages/home.html": "index.html",
}
INDEX_SAVE_AS = "posts.html"
MENUITEMS = [
    ("posts", "posts.html"),
]

References

Open points