Portfolio/content/posts/2026-09-08-hello.md
2026-09-08 19:54:06 +02:00

60 lines
2.1 KiB
Markdown

---
title: how this blog works
description: markdown in a git repo, a webhook, and no build step. here is the whole thing.
date: 2026-09-08
tags: [meta, nuxt, gitea]
draft: false
---
This post is a file. It lives in a git repo, it has YAML frontmatter, and pushing
it is the entire publishing pipeline. No CMS, no rebuild, no `npm run deploy`.
## the shape of a post
Everything above the second `---` is frontmatter:
```yaml
---
title: how this blog works # required-ish; falls back to the filename
description: one line, used in the # optional; falls back to the first paragraph
list view and the og tags
date: 2026-09-08 # optional; falls back to a YYYY-MM-DD filename prefix
updated: 2026-09-09 # optional
tags: [meta, nuxt, gitea] # optional; also accepts "meta, nuxt"
slug: how-this-blog-works # optional; falls back to the filename
draft: false # true hides it in production
---
```
The filename becomes the slug, with a leading date stripped:
`2026-09-08-hello.md` → `/blog/hello`.
## how it gets here
1. You push to the content repo.
2. Gitea fires a webhook at `/api/webhook/content` with an HMAC signature.
3. The server checks the signature, drops its cache, and re-reads the tree.
4. The next request renders from the fresh copy.
If the webhook never fires — network hiccup, misconfigured secret — the cache
still expires on its own after `CONTENT_TTL` seconds. And if the repo is down
when a refresh is due, the last good copy keeps being served instead of a 502.
## code and images
Fenced blocks are highlighted server-side by Shiki, in both themes at once:
```rust
fn main() {
let payload = std::fs::read_to_string("post.md").expect("a post");
println!("{} bytes, zero javascript", payload.len());
}
```
Relative image paths resolve against the post's own directory in the repo, so
`![a diagram](./diagram.png)` works if you commit the png next to the markdown.
> Blockquotes, tables, and lists all render. Anything markdown-it understands.
That's it. Write a file, push, done.