|
|
@@ -0,0 +1,35 @@
|
|
|
+# Add Markdown blog server
|
|
|
+
|
|
|
+Branch `feature/initial` · merged 2026-10-24 · version (none; later called 0.1.0)
|
|
|
+
|
|
|
+## What changed
|
|
|
+
|
|
|
+- **Blog server:** a Go app that serves each `content/*.md` file as a blog post.
|
|
|
+ - `/` lists all posts, newest first, with title, date and summary.
|
|
|
+ - `/posts/<slug>` shows one post, with links to the newer and older posts.
|
|
|
+ - `/feed.xml` is an RSS feed of the 20 newest posts.
|
|
|
+ - Any other URL gets a styled 404 page.
|
|
|
+- **Posts:** named `YYYY-MM-DD-slug.md`, with an optional front-matter block for `title`, `date`, `summary` and `draft`. If the title is missing, the first `# Heading` is used, then the slug. If the date is missing, it comes from the filename.
|
|
|
+- **Live content:** posts are re-read whenever a file in the content directory is added, changed or removed, so new posts appear without a restart.
|
|
|
+- **Fault tolerance:** a post with a bad filename or broken front matter is skipped and logged; the rest of the site keeps working.
|
|
|
+- **Markdown:** rendered with goldmark (CommonMark plus GitHub-style tables, strikethrough, task lists and autolinks). Raw HTML in posts is left out.
|
|
|
+- **Templates and CSS:** built into the binary. The layout is minimal, with automatic dark mode.
|
|
|
+- **Security:** URLs can only reach posts that have been indexed, so `../` paths get a 404. Responses carry a strict Content-Security-Policy (no scripts), `nosniff` and a referrer policy. The server binds to `127.0.0.1` with request timeouts.
|
|
|
+- **Configuration:** set by environment variables `PORT`, `CONTENT_DIR` and `SITE_URL`.
|
|
|
+- **First post:** `content/2026-10-24-hello-world.md`, a guide to writing posts covering file names, the header block, publishing, and what Markdown is supported.
|
|
|
+
|
|
|
+## Testing
|
|
|
+
|
|
|
+- `go vet` is clean and all tests pass with the race detector (`go test -race ./...`), with 81% coverage.
|
|
|
+- Tests cover front-matter parsing and fallbacks, CRLF files, drafts, ordering, newer/older links, 404s including path-traversal attempts, the RSS feed, static files, security headers, and picking up added and removed posts.
|
|
|
+- Built and ran locally against the real `content/`, then checked the index, the post and the feed.
|
|
|
+
|
|
|
+## Screenshots
|
|
|
+
|
|
|
+Taken afterwards from a build of the branch's final commit (`0bd42c4`).
|
|
|
+
|
|
|
+| Desktop | Mobile |
|
|
|
+|---|---|
|
|
|
+|  |  |
|
|
|
+
|
|
|
+🤖 Generated with [Claude Code](https://claude.com/claude-code)
|