Site Update · June 13, 2026
Making blog posts a real model
One of the quieter changes in this site refresh was moving blog posts out of one-off template edits and into a real BlogPost model. That sounds like a small model update, but it changes the way the site can grow. A post now has a title, slug, status, publish date, body, and timestamps that belong to the application instead of being scattered through static markup.
That move was smart because it gives the writing side of the site the same kind of shape as the rest of the project. Published posts can be queried, sorted, counted, previewed on the home page, and shown on their own stable URLs. Drafts can exist without being public. The admin dashboard can surface the latest publishing activity. Most importantly, adding a post no longer means inventing another little content path by hand.
I also like that the model gives future work somewhere obvious to land. Tags, RSS, better excerpts, scheduled publishing, search, or project-specific post collections can all build on the same table instead of needing a new static convention each time. Even if I never add every one of those ideas, the current shape keeps the door open without making the first version heavy.
The implementation stayed intentionally plain. Markdown is stored as source text, rendered through a CommonMark parser, and cleaned before it reaches the page. The public routes use date pieces plus a slug, so URLs are readable and stable. Publication fields are denormalized just enough to make uniqueness and routing straightforward: the date is available as a real date, and the published day key protects against accidentally publishing two public posts on the same day.
The admin flow was another practical part of the change. I can create, edit, preview, publish, and unpublish posts from the site itself, while older launch posts can still be seeded through migrations when that is the right tool. This entry is doing exactly that, which feels fitting: the blog system is now content, data, and deployment working together instead of a pile of special cases in templates.