External Publication
Visit Post

Hacking on my blogging workflow

Home — Terracrypt [Unofficial] April 5, 2026
Source

Starting December Adventure off with a little meta this year (and a bit late, whoops!). Since setting up this blog, it's always felt like a little too much friction to start a new blog post. It's not too bad, but it does involve creating a file in the posts directory with a given name, manually typing out the timestamp.

I'm always writing my blog posts in emacs anyway, and emacs is the most hackable of editors. So I figured, why not have a template to make things easier?

I'm a heavy user of org-capture to quickly add entries to my TODO list. Although my blog posts are markdown rather than org-mode (for now?), org-capture seemed flexible enough to do the job. And sure enough, it was!

It felt a little gross to do this, but I ended up setting a global variable for the post slug. I tend to use the slug as the filename of each post file, and I didn't want to be prompted for the slug twice. Org-capture can accept a function that controls the file path to capture to; having that function prompt me and save the result seemed like an okay solution.

(defun jfred/capture-blog-post () (interactive) (let ((name (read-string "Post slug: "))) (setq jfred-capture-blog--slug name) (expand-file-name (format "%s.md" name) "~/src/website/posts")))

After that, it was a matter of defining a plain org-capture template to start a new file when captured. I'll just show you all my capture templates so you have the new one in context:

(setq org-capture-templates '(("t" "Todo" entry (file "~/org/Inbox.org") "* TODO %?\n %a") ("tn" "Todo - no link" entry (file "~/org/inbox.org") "* TODO %?") ("j" "Journal" entry (file+olp+datetree "~/org/journal.org") "* %?\nEntered on %U\n %i\n %a") ("b" "Blog post" plain (file jfred/capture-blog-post) "title: %^{title} slug: %(format jfred-capture-blog--slug) tags: date: %<%Y-%m-%d %H:%M:%S> --- %?") ("m" "Meeting Notes" entry (file+olp+datetree "~/org/meetings.org") "* Meeting Notes - %?")))

(As an aside, I just realized while looking at these that the tn capture doesn't actually work and would be useful. Guess I'll fix that up soon!)

I can tell that the org-capture template system is really meant for templating org files, but it worked here. There's a template string representing a timestamp, but it defaults to the format that org-mode expects; if you want a timestamp in a specific format, you have to use more explicit formatting. But you can do that!

That's all for today. Today's the first day of my holiday break, so I hope to have more time to work on side projects for the rest of the month. My goal this holiday season is to get guile-horton finally supporting persistence. It's not very useful without it, but I did a few things that were perhaps a bit too clever when originally writing it, so it'll likely be annoyingly complicated to get that working. Fingers crossed!

Discussion in the ATmosphere

Loading comments...