every blog needs subheader text

blogging in python

Table of contents.

There are many excellent blog engines out there, but to customise any of them takes so much understanding of how they work, the template and theme engines they use, that its easier to just use them exactly as is with an existing theme.

I wanted my own custom static blog, which played well with jupyter notebooks and markdown files, as well as a reason to do some python coding, so here goes yet another python blogging engine.

This post documents the process of building this blog. The main goal is to put markdown and jupyter notebooks in a folder, and build a static site which gets autoupdated on github pages or netlify. Just like hugo, jekyll, gatsby and so many others!

blog engine

Its straightforward to read a set of markdown posts and convert to python. I am using python to read the posts with python-markdown to parse them into html, complete with inline syntax highlighting.

Key tools used:

Below are notes for the specifics used.

parsing markdown

Python markdown

Start a server from cli:

python -m http.server

notebooks to markdown

I started with nbdev to convert notebooks to markdown, but it slowed down rebuilding the blog a lot, and its pretty complex. So in the end I've stuck with nbconvert. Some useful tips:

I need to customize nbconvert so it implements some of the features from fastpages, namely:

code highlight

python markdown has pygments built in, which has a bunch of styles. To generate the css:

pygmentize -S default -f html -a .codehilite > codestyles.css

But on second thought decided to can this and go with highlightjs for now as it speeds up builds and keeps the html clean (at the cost of loading more javascript).

One thing to investigate is how to make the output cells of jupyter notebooks blend into the main website. This seems to require some css trickery.


I'm no longer familiar with html, even though I build my first weblog on geocities way back in 1997/8. So we have now reached html5.


CSS is hard. So I want a simple to use framework, ended up looking at:

todo: decide on one.

Things to implement using css:

Search. I want search. This is pretty straightforward, we need a list of content and some javascript to do the searching. Jupyter notebooks mess this up as the converted markdown files have a bunch of js and other cruft.

To just search post titles is pretty easy, from direct js to algolias autocomplete library.

Ideally I want to search across all the content is well, which takes some thinking as the output of jupyter notebooks can be huge, with all kinds of js embedded.

Some things to look at:

So step one is to build a search index - which my script does as a json file containing all the post attributes I want searched.

Github actions

Github actions add superpowers to a repo - they can be set to be triggered at a time interval or on every code push to a branch. To make a github action: Save a github approved formatted yaml file to .github/workflows folder and it should run on every push. For this blog my actions:

Misc stuff


Some unicode fonts have emojis built in, so ways to enable emoji is:

Emoji test:

twitter embed

This should show a twitter tweet embedded inside the page:

testing syntax highlight

from mako.template import Template
from mako.lookup import TemplateLookup
lookup = TemplateLookup(directories=["templates"])

# make the big picture templates
for tmpl in ["index.html"]:
    template = lookup.get_template(tmpl)
    html = template.render(posts=posts).strip()
    path = path_publish / tmpl
    print(f"wrote {tmpl} to {path}")

# write all the posts
template = lookup.get_template("post.html")
for post in posts:
    html = template.render(post=post).strip()
    path = path_publish / f"{post.slug}.html"
    print(f"wrote {post.slug} to {path}")
posted , updated
tagged: python View on: github