99 lines
2.7 KiB
Go
99 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
|
|
chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
|
|
"github.com/alecthomas/chroma/v2/styles"
|
|
|
|
"ridgwaysystems.org/website/internal/blog"
|
|
"ridgwaysystems.org/website/internal/handler"
|
|
)
|
|
|
|
func main() {
|
|
port := getenv("PORT", "8080")
|
|
contentDir := getenv("CONTENT_DIR", "content")
|
|
dataDir := getenv("DATA_DIR", "data")
|
|
|
|
// Generate syntax.css at startup (light + dark via media query)
|
|
if err := generateSyntaxCSS("static/css/syntax.css"); err != nil {
|
|
log.Printf("warning: could not generate syntax.css: %v", err)
|
|
}
|
|
|
|
store, err := blog.NewStore(contentDir + "/posts")
|
|
if err != nil {
|
|
log.Fatal("store:", err)
|
|
}
|
|
|
|
h := handler.New(store, dataDir)
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
// Static files (includes robots.txt via static/robots.txt)
|
|
mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
|
|
|
|
// robots.txt at root
|
|
mux.HandleFunc("GET /robots.txt", func(w http.ResponseWriter, r *http.Request) {
|
|
http.ServeFile(w, r, "static/robots.txt")
|
|
})
|
|
|
|
// Public routes
|
|
mux.HandleFunc("GET /{$}", h.Index)
|
|
mux.HandleFunc("GET /blog", h.BlogList)
|
|
mux.HandleFunc("GET /blog/feed.xml", h.Feed)
|
|
mux.HandleFunc("GET /blog/{slug}", h.BlogPost)
|
|
mux.HandleFunc("GET /infrastructure", h.Infrastructure)
|
|
mux.HandleFunc("GET /status", h.Status)
|
|
mux.HandleFunc("GET /about", h.About)
|
|
mux.HandleFunc("GET /hire", h.Hire)
|
|
mux.HandleFunc("POST /hire", h.HirePost)
|
|
mux.HandleFunc("GET /resume", h.Resume)
|
|
mux.HandleFunc("GET /sitemap.xml", h.Sitemap)
|
|
|
|
// Admin routes (auth handled per-handler)
|
|
mux.HandleFunc("/admin", h.AdminDashboard)
|
|
mux.HandleFunc("/admin/", h.AdminRouter)
|
|
|
|
srv := handler.Chain(mux,
|
|
handler.LoggingMiddleware,
|
|
handler.SecurityHeadersMiddleware,
|
|
)
|
|
|
|
log.Printf("ridgwaysystems.org starting on :%s (DEV=%s)", port, os.Getenv("DEV"))
|
|
log.Fatal(http.ListenAndServe(":"+port, srv))
|
|
}
|
|
|
|
// generateSyntaxCSS writes a chroma CSS file with light and dark themes.
|
|
func generateSyntaxCSS(path string) error {
|
|
formatter := chromahtml.New(chromahtml.WithClasses(true))
|
|
|
|
var buf bytes.Buffer
|
|
|
|
// Light theme (github)
|
|
buf.WriteString("/* Auto-generated by chroma at server startup. Do not edit. */\n\n")
|
|
if err := formatter.WriteCSS(&buf, styles.Get("github")); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Dark theme wrapped in prefers-color-scheme media query
|
|
buf.WriteString("\n@media (prefers-color-scheme: dark) {\n")
|
|
var dark bytes.Buffer
|
|
if err := formatter.WriteCSS(&dark, styles.Get("github-dark")); err != nil {
|
|
return err
|
|
}
|
|
buf.Write(dark.Bytes())
|
|
buf.WriteString("}\n")
|
|
|
|
return os.WriteFile(path, buf.Bytes(), 0644)
|
|
}
|
|
|
|
func getenv(key, def string) string {
|
|
if v := os.Getenv(key); v != "" {
|
|
return v
|
|
}
|
|
return def
|
|
}
|