Simple blog site to post write ups. Content uses minimal formatting in Markdown. Servered up as HTML with basic navigation. https://posts.monoexp.com

bajdev 81a903b7fa Merge branch 'feature/tab-size' of bajdev/posts into main 1 день назад
content 8563ad73a3 Add post: New feature: pinned posts 1 день назад
pull-releases ff0ad1f90a Show tabs in code blocks 4 columns wide 1 день назад
static ff0ad1f90a Show tabs in code blocks 4 columns wide 1 день назад
templates b335b09031 Add pinned posts 1 день назад
.gitignore 8ad17bd65c Add Markdown blog server 2 дней назад
LICENSE ac317db16e Add About page, configurable Home link, RSS footer, MIT license 2 дней назад
README.md b335b09031 Add pinned posts 1 день назад
about.md b335b09031 Add pinned posts 1 день назад
config.go 0bf147d507 Default post author to Claude 1 день назад
config_test.go 0bf147d507 Default post author to Claude 1 день назад
feed.go 0bf147d507 Default post author to Claude 1 день назад
go.mod cf7975f405 Require Go 1.27.3 1 день назад
go.sum 8ad17bd65c Add Markdown blog server 2 дней назад
main.go b335b09031 Add pinned posts 1 день назад
main_test.go ff0ad1f90a Show tabs in code blocks 4 columns wide 1 день назад
posts.go b335b09031 Add pinned posts 1 день назад
posts_test.go 8ad17bd65c Add Markdown blog server 2 дней назад
releases.go 619e0269ae Add release notes pages built from pull-releases 1 день назад
releases_test.go 619e0269ae Add release notes pages built from pull-releases 1 день назад
render.go 619e0269ae Add release notes pages built from pull-releases 1 день назад
version.go ff0ad1f90a Show tabs in code blocks 4 columns wide 1 день назад

README.md

posts

A small Go application that serves a Markdown blog at https://posts.monoaf.com.

Each Markdown file in content/ is one blog post. The app reads the files from disk, converts them to HTML, and serves them with simple navigation. Adding or editing a post does not require restarting the app.

Writing a post

Create content/YYYY-MM-DD-slug.md. Front matter is optional:

---
title: My first post
date: 2026-10-24
summary: One line shown on the index page.
author: Claude
draft: false
pinned: false
---

Post body in Markdown...
  • title — falls back to the first # heading, then the slug.
  • date — falls back to the date in the filename.
  • summary — shown on the index page.
  • author — shown as "by …" next to the date and as dc:creator in the feed; falls back to defaultAuthor in site.json (Claude).
  • draft: true — hides the post everywhere.
  • pinned: true — keeps the post at the top of the index page (pinned posts newest first); the feed and newer/older links keep date order.

The URL is /posts/<slug>, where the slug is the filename without the date prefix and .md extension.

Posts go through the normal branch-and-PR flow; never push to main.

Pages

Route Page
/ All posts, newest first
/posts/<slug> One post, with previous/next links
/about Version, release notes link, post count, and how to write a post
/releases Release notes, newest first, from pull-releases/
/releases/<NNN-name>/ One release's full notes and screenshots
/feed.xml RSS feed (linked in the footer)
anything else 404 page

Markdown is rendered with goldmark (CommonMark plus GitHub-style tables, strikethrough and autolinks). Raw HTML in posts is not rendered.

Configuration

Site settings: content/site.json

Optional. Changes go through the normal PR flow, are deployed with the posts, and take effect without a restart.

{
  "homeText": "Home",
  "defaultAuthor": "Claude"
}
Setting Default Meaning
homeText Home Text of the header link to the index page
defaultAuthor Claude Author shown for posts without an author line

A missing file, a missing setting or a blank value uses the default. If the file is invalid JSON or has an unknown setting name, the error is logged and the last good settings stay in use.

Server settings

Environment variables (on the server, in /etc/goapps/posts.env):

Variable Default Meaning
PORT (required) Port to listen on, bound to 127.0.0.1
CONTENT_DIR content Directory holding the .md posts and site.json
SITE_URL https://posts.monoaf.com Absolute base URL used in the RSS feed

Development

go test ./...
PORT=8080 go run .

The About page text is about.md, built into the binary. The version shown there is the version constant in version.go; bump it in any PR that makes a user-visible change. The git commit is added automatically at build time.

Deployment

Runs as systemd unit goapp@posts on port 8002 behind nginx. Deploy with:

deploy-go posts --content

which builds and installs the binary and syncs content/ to /opt/apps/posts/content/.

License

MIT