Kontra: GOTH app (Go+templ+htmx+Tailwind tokens), markdown content, Decap admin, media shortcodes. Phase 3 build complete + verified locally.
This commit is contained in:
57
app/src/main.go
Normal file
57
app/src/main.go
Normal file
@@ -0,0 +1,57 @@
|
||||
// Kontra — news-opinion site. Single static binary.
|
||||
// Serves markdown content as HTML per request (GOTH stack).
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
// bundled static assets + admin UI (served under /web/)
|
||||
//go:embed web
|
||||
var web embed.FS
|
||||
|
||||
func main() {
|
||||
root := os.Getenv("KONTRA_CONTENT")
|
||||
if root == "" {
|
||||
root = "content"
|
||||
}
|
||||
|
||||
mediaBase := os.Getenv("KONTRA_MEDIA")
|
||||
if mediaBase == "" {
|
||||
mediaBase = "/media"
|
||||
}
|
||||
|
||||
c, err := NewContent(root, mediaBase)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to load content from %s: %v", root, err)
|
||||
}
|
||||
log.Printf("loaded %d articles across %d subjects", len(c.Articles), len(c.Subjects))
|
||||
|
||||
s := NewSite(c)
|
||||
|
||||
// Routes — register specific paths BEFORE the catch-all.
|
||||
http.HandleFunc("/subjects/{slug}", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.subject(w, r, r.PathValue("slug"))
|
||||
})
|
||||
http.HandleFunc("/articles/{slug}", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.article(w, r, r.PathValue("slug"))
|
||||
})
|
||||
http.Handle("/web/", http.FileServerFS(web))
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
s.home(w, r)
|
||||
})
|
||||
|
||||
port := os.Getenv("PORT")
|
||||
if port == "" {
|
||||
port = "8080"
|
||||
}
|
||||
addr := ":" + port
|
||||
log.Printf("Kontra listening on %s (content: %s)", addr, root)
|
||||
if err := http.ListenAndServe(addr, nil); err != nil {
|
||||
log.Fatalf("server error: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user