How_the_Blog_Works

I hate to talk shop on the weekend but

I thought it might be good to share how the blog works on a technical level because so far I am very happy with how it works.

As a child of the early internet, it is my unshakeable belief that one can get just about anything for free if they do not value their time. While I may not value my time I do value yours dear reader, so I am not going to explain every aspect of the site here but just the mechanism for the blog.

In order to avoid using WordPress or any other god awful CMS, the blog was designed to run on git, and obsidian + a couple of extensions. This system could probably be refined, and as that happens new posts will be added documenting what has changed, why and how.

The first thing to know is that the blog is a portion of a larger Astro application, but the core Obsidian/git interplay is contained in repository-root/src/content/blog. To connect the vault to the local instance of the repo, an Obsidian vault is initialized in the /blog directory. Riveting right? The current state of the /blog directory is:

repository-root/                    ← main git repo (Astro project)
└── src/content/blog/           ← Obsidian vault root
    ├── .obsidian/              ← Obsidian config (git-ignored)
    │   └── plugins/
    │       ├── obsidian-git/
    │       └── templater-obsidian/
    ├── _templates/
    │   └── blog-template.md.md
    ├── Tesla_BLE_Scanner.md
    ├── How the Blog Works.md
    └── ..

Right now the /.obsidian directory is ignored by git, this was done reflexively because the developer was too lazy to configure the build script to ignore it and did not want to bundle it unnecessarily with the application. This is an improvement that will likely be implemented at another time, it makes the most sense to make the Obsidian plugins’ configuration available to whatever device clones the repo to speed up the process of setting up on a new machine.

speaking of Obsidian plugins

The blog uses the Templater and Git plugins. Templater scaffolds new files with frontmatter, that’s the YAML block at the top of each markdown file. This means when I create a new file, Obsidian automatically generates the metadata that Astro expects for a blog post and prompts the user to input the requisite data. Astro validates this frontmatter using Zod, a schema validation library. There is a config in the src/content directory that defines the required fields, and the build will fail if a post doesn’t match that schema.

---
title: How the Blog Works

pubDate: 2026-02-13T19:06:21

description: How the Blog Works

author: dudgy

tags:

  - obsidian

  - astro

  - typescript

  - javascript

  - html

  - scss

  - css

  - cms

draft: true
---

A couple of these properties have some associated logic:

  1. Clicking a tag in the UI will show the user a list of all of the posts with that tag.
  2. Draft is used by the frontend to hide posts that are still cooking. The issue with this is that drafts are vulnerable, if a user could guess a post’s title and append it to the URL like this https://wintermute.world/blog/this-is-a-draft, they would be able to see posts that are not ready for human consumption. To combat this I am using a separate github branch to manage drafts, as my hosting provider is only rigged up to deploy builds from the main branch.

There is probably a more elegant way to do this… one second…

OK I am back, the drafts are now excluded from the build, a bit more of an elegant solution in case git branches become unwieldy, and it will keep the build smaller. I’m not sure I would want to be merging PRs to post to my blog long term since I do that enough at work.

The Git extension

is used to automatically commit and push every 10 minutes, with a nightmare inducing commit msg: "vault backup: {{date}}". This could almost certainly be improved to include the title of the file being worked on or anything really to make it easier to read. When a post is taken out of draft status it will be auto-committed and pushed to main. Holy shit this must be so boring, anyway:

┌─────────────────────────────────────────────────────────────┐
│  VERSION CONTROL (obsidian-git plugin)                      │
│                                                             │
│  Auto-commits every 10 minutes                              │
│     Commit message: "vault backup: {{date}}"                │
│                                                             │
│  Pull on boot: yes (rebase strategy)                        │
│  Auto-push: on (can be set to manual                        |
|      if you don't want to autocommit)                       │
│  obsidian-git syncMethod:	rebase	(Clean linear history)    |
|                                                             │
│  Result: local git history of every editing session         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Sounds perfect right? A cross-platform, portable micro-cms with local and remote backups for free

You’d be dead wrong, there are some grave problems that need to be dealt with and improvements that should be made. The obvious ones we already covered above but to recap

  • The auto-generated commit message is dog shit, it needs to reflect something meaningful to make the git log understandable.
  • The .obsidian directory should probably be included in the repo to make the editor setting more portable. But I want to really dial in my set-up before publishing it, for now I am only writing on one machine.
  • The drafts may be accessible before they have reached a safe temperature if the url can be guessed
    • oh hell yeah this was actually fixed before the post was finished.
  • I didn’t talk about images yet because embarrassingly I haven’t really given enough thought to how I want to handle them. Astro has given me a lot to consider in terms of the way images are loaded and referenced in the .md files. If you haven’t noticed I really like not including stuff in the build, so I am going to look at hosting them somewhere. I also really like not paying for stuff, so I have to invest some of my worthless worthless time to figure out how to resolve that.
  • The published time and the created time that is auto-generated in the frontmatter are both a reflection of when the file was created, not when it was published. I like the idea of being transparent about how long a piece took to write, so I think I will look into how I want to update the published time to be when the draft was pushed to git. If I ever feel embarrassed about how long it is taking to write a post, I can still change the Created on date to make it seem like I wrote the piece much faster. There is literally nothing you can do to stop me.
  • I would like to eventually pull the blog functionality out and make it a consumable package, maybe published to npm to make the entire project truly portable.

Didn’t someone mention respecting the dear reader’s time?

To be sure. As the development of the blog proceeds, more extremely boring posts will follow. The metatag will be used for posts that pertain to the development of any aspect of this site.


Created on 2026-02-13 at 19:06