How to create this website (again)
While ruby looks shiny at first, mentaining all the packages only for my website was not my gem. 🥁 It was time to abandon ship and switch to a static site generator written in python, enter pelican!
To get started, install pelican and use the
pelican-quickstart
command to set up the initial structure: Pelican follows a simple directory structure:
my_blog/
├── content/
│ ├── articles/
│ ├── pages/
│ └── images/
├── themes/
├── pelicanconf.py
└── publishconf.py
where content/ holds all the markdown files, themes/ contains the theme files, and the configuration files pelicanconf.py and publishconf.py define settings for development and production respectively.
Articles and pages are written in markdown.
The difference between the two is that articles meant to be time-sensitive and usually include metadata like title, date, and tags, while pages are static and often used for content like "About Me" or "Contact".
Recently, I am a fan of uv for running python applications, so I set up a pyproject.toml file to manage dependencies, here is a sample with some nice pelican plugins:
[project]
name = "my_blog"
version = "1.0.0"
requires-python = ">=3.13"
dependencies = [
"pelican[markdown]>=4.11.0",
"minchin-pelican-plugins-summary>=1.3.0",
"typogrify>=2.1.0",
"beautifulsoup4>=4.14.3",
"pelican-neighbors>=1.2.0",
"pelican-render-math>=1.0.5",
]
And use a simple Makefile
PELICAN := $(shell command -v uv >/dev/null 2>&1 && echo "uv run pelican" || echo "python3 -m pelican")
BASEDIR=$(CURDIR)
INPUTDIR=$(BASEDIR)/content
OUTPUTDIR=$(BASEDIR)/output
CONFFILE=$(BASEDIR)/pelicanconf.py
PUBLISHCONF=$(BASEDIR)/publishconf.py
clean:
rm -rf $(OUTPUTDIR)
publish:
$(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(PUBLISHCONF)
serve:
$(PELICAN) -lr $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) -b 0.0.0.0 -p 8000
.PHONY: clean publish serve