Blog Home

Leveling Up My Blog

May 11, 2025

The first rev of my blog has been doing fine, but I really wanted something a little bit richer and easier to navigate. I wanted a page for each post as well as a homepage that shows all the posts in order. I also wanted to add an RSS feed (as requested by my coworker Michael).

I started out by moving my blog out from under my homepage project into its own dedicated site. I also gave it a new URL, blog.jamesmassucco.com. While adding this into my cloudflare-ddns container configuration (which, by the way, makes it insanely easy to establish new subdomains directly in code), I realized that it was clunky to be defining my list of domains in a gitignore'd .env file and so I moved it into the docker-compose.yml. Now it'll be even easier to add (and keep track of) new subdomains, since I seem to be adding at least 1~2 of them every week!

The first thing I did was restructure my markdown files to have a proper metadata section. I used the frontmatter specification, which allows encoding metadata by inserting a block like this at the top of a file:

---
title: 'Leveling Up My Blog'
date: '2025-05-11'
tags: [blog]
summary: 'Turning my blog into a dedicated app with a page for each post'
slug: blog-levelup
---

The title and date were already existing. I added tags for potential future use, the summary for displaying on the main page, and slug will be the name of each posts' HTML page (e.g. blog.jamesmassucco.com/posts/blog-levelup.html). Parsing the data out is pretty simple - just import frontmatter in python and then frontmatter.load(<md_path>) and you get a result with content and metadata. The content was the same as the markdown I was used to working with (doesn't include the metadata), while the metadata made available a dictionary of key-value pairs with the metadata I had encoded. To make it easier to access the metadata, I created a pydantic class so that instead of metadata['title'], I could do metadata.title. I hate typing quotation marks lol. I also added a class to represent each blog post, handle parsing it with frontmatter, and do a few more convenience functions.

Once I had all the posts parsed, I needed to generate 3 sets of outputs:

  1. An index.html to serve as the new blog homepage
  2. A <post-slug>.html for each blog post
  3. An rss.xml to provide RSS feed functionality

For each of these, I created a jinja2 template. Jinja is a powerful python templating engine. It allows you to write a document (e.g. html) that includes special tags like {{ post.metadata.date }}, and then feed in a post object to the render operation and it will replace the {{ }} blocks with rendered data from your object. It also has a very useful for-loop function, and a few other functions that proved useful for this exercise. I used ChatGPT to get basic versions of each of the 3 templates, and then spent some time tweaking them to fit the style of the rest of the site. After an hour or so, the site was looking pretty rad.

To finish it off, I killed off the old static blog and replaced it with a link to this new blog.jamesmassucco.com I also made each blog post page include a Blog Home button in the top-left, as opposed to the typical Home button found on the other pages. That way, if someone is viewing a blog post, they can click back to the main page of the blog. The main page of the blog then includes a Home link to go back to the main site home, but I figured if someone is reading a blog post, it's more likely that they want to go back to the blog index than the top-level site home. Maybe sometime soon I'll add some more navigational functionality - but this should work fine for now.