Files
kontra/.pi/memory-vault/packs/kontra-day/40-actions/2026-09-08-kontra-phase-3-build-goth-app-complete-golang-gotchas.md
sam 0876512f1c feat: employer-showcase README with architecture map + publish to maps.lab; Mermaid + Archify project diagrams
- docs/kontra-architecture.mmd (mermaid source) + rendered PNG/SVG
- docs/kontra-architecture-map.html (interactive Archify, validated + visual-checked)
- docs/architecture.md (doc with embedded mermaid)
- README.md (showcase: stack, content model, design system, deploy, security)
- published docs/ to https://maps.lab.audasmedia.com.au/kontra_day/docs/

[secret-scan: skip - false positive on generated mermaid SVG path data]
2026-09-09 11:49:52 +10:00

64 lines
3.3 KiB
Markdown

---
type: action
id: action.kontra-day.kontra-phase-3-build-goth-app-complete-golang-gotchas
title: Kontra Phase 3 build — GOTH app complete + golang gotchas
status: active
source_of_truth: false
freshness: current
last_reviewed: 2026-09-08
tags:
- pack/kontra-day
- agent-memory/action
- kontra
- golang
- templ
- goldmark
- goth
- build
---
# Kontra Phase 3 build — GOTH app complete + golang gotchas
# Kontra — Phase 3 build complete (verified local)
## What was built (2026-09-08)
GOTH stack app at `/home/sam/home_network/web_sites/kontra_day/app`:
- **golang 1.26.2** (the "Go" in GOTH is golang, NOT Rust-like Go — vgo.mod uses `require (...)` blocks, `package main`, `func main()`).
- **templ v0.3.1020** — CLI at `~/go/bin/templ` (installed via `go install github.com/a-h/templ/cmd/templ@latest`, path must be on PATH). `.templ` files in `app/src/`, generated with `templ generate` (writes `*_templ.go`), build with `go build -o kontra-bin .` from `app/src/`. Build script: `app/build.sh`.
- **goldmark v1.8.6** markdown + **goccy/go-yaml v1.19.2**.
- Single static binary ~11.5MB. `PORT` and `KONTRA_CONTENT` and `KONTRA_MEDIA` env vars.
## Key golang gotchas (learned the hard way)
- `[start:end]` slices PANIC (bounds) if end > len — clamp first! Use helper `firstArticles(a, n)`/`firstSubjects`.
- No ternary operator; templ `{}` interpolation doesn't support inline `if/else { }` expressions — use block-level `if` between elements, and `templ.KV(" active", cond)` for conditional classes.
- `//go:embed web` keeps FULL path in the virtual FS → root = `web/`, files at `web/assets/kontra.css`. Serve with `http.Handle("/web/", http.FileServerFS(web))`. Route patterns need trailing-slash (`/web/`) plus `/` catch-all registered LAST.
- Route specificity works but registers specific before `/`.
- go-yaml lowers struct field names for keys by default — use lowercase YAML keys (name/tagline/defaulttemplate/subjects/label/slug).
- log: `log.Printf`/`log.Fatalf` (no log.Errorf).
- golang stdlib net/http: `http.Handle(pattern, handler)`, `http.HandleFunc`, `http.ListenAndServe(":8080", nil)`, `r.URL.Path`, `r.PathValue("slug")`. Patterns: `/subjects/{slug}`.
- All source files `package main`; go.mod `module day`.
## Content model
`content/` tree: `config/site.yaml`, `subjects/<slug>/_subject.yaml` + `*.md`, `pages/*.md`. Front-matter keys lowercase: title/author/date/kicker/template/subject/image/excerpt/featured/published. Shortcodes `{{media:name}}`→`KONTRA_MEDIA` base + `/name`; `{{embed:vimeo:ID}}`→iframe. Resolved on RAW markdown BEFORE goldmark so links work.
## Admin
Decap CMS at `app/src/web/admin/` (index.html + config.yml): git-gateway backend → Gitea, collections articles/subjects/pages + editorial workflow. Served at `/web/admin/`.
## Verified routes (local smoke test, PORT=8691)
/, /articles/{slug}, /subjects/{slug}, /web/assets/kontra.css, /web/admin/ → all 200. 404 for missing article/subject.
## Git
Committed to local repo (no remote yet): commit 31e9a70. `.pi/` memory vault is inside the repo too.
## Not done yet (task 7)
Gitea remotes (.35), Obsidian vault, .13 systemd service + 30s git pull timer, Caddy routes (kontra.domain + admin), Decap git-gateway OAuth app.
## Evidence
- Confidence: 100%
- Reason: Manual memctx_save
## Related
- [[packs/kontra-day/00-system/pi-agent/memory-manifest|Memory Manifest]]