121 lines
2.5 KiB
Go
121 lines
2.5 KiB
Go
package site
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"html/template"
|
|
"net/http"
|
|
"net/url"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/angelbeltran/templater"
|
|
|
|
"ruben/inventory2/internal/domains/raw_events"
|
|
)
|
|
|
|
func NewSiteHandler(dir string, db *raw_events.Store) http.Handler {
|
|
mux := http.NewServeMux()
|
|
|
|
// non-html routes
|
|
|
|
scfs := http.FileServer(http.Dir(dir + "/scripts"))
|
|
mux.Handle("/scripts/", http.StripPrefix("/scripts", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "text/javascript")
|
|
if path.Ext(r.URL.Path) == ".gz" {
|
|
w.Header().Set("Content-Encoding", "gzip")
|
|
}
|
|
scfs.ServeHTTP(w, r)
|
|
})))
|
|
mux.Handle("/styles/", http.StripPrefix("/styles", http.FileServer(http.Dir(dir+"/styles"))))
|
|
|
|
// html page routes
|
|
|
|
tmplr := templater.NewTemplater(
|
|
dir+"/templates",
|
|
func() template.FuncMap {
|
|
return template.FuncMap{
|
|
"buildSitePath": func(parts ...any) string {
|
|
strParts := make([]string, len(parts))
|
|
for i, p := range parts {
|
|
strParts[i] = fmt.Sprint(p)
|
|
}
|
|
|
|
// TODO: make "/site" dynamic somehow
|
|
return path.Join(append([]string{"/site"}, strParts...)...)
|
|
},
|
|
|
|
"prettyPrintJSON": func(j json.RawMessage) string {
|
|
b, err := json.MarshalIndent(j, " ", "")
|
|
if err != nil {
|
|
return string(j)
|
|
}
|
|
return string(b)
|
|
},
|
|
|
|
"addInt": func(a, b int) int {
|
|
return a + b
|
|
},
|
|
"subInt": func(a, b int) int {
|
|
return a - b
|
|
},
|
|
"multInt": func(a, b int) int {
|
|
return a * b
|
|
},
|
|
}
|
|
},
|
|
)
|
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
b, err := tmplr.ExecutePage(
|
|
getPageTemplateNameForURL(r.URL),
|
|
"Request",
|
|
r,
|
|
// add services here
|
|
"RawEvents",
|
|
db.WithContext(r.Context()),
|
|
"URLCalc",
|
|
newURLCalculator(r.URL),
|
|
)
|
|
if err != nil {
|
|
// TODO: handle 'not found' as a 404?
|
|
fmt.Println("[ERROR]: failed to load or parse layout template:", err)
|
|
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
|
|
return
|
|
}
|
|
|
|
w.Write(b)
|
|
})
|
|
|
|
return mux
|
|
}
|
|
|
|
func getPageTemplateNameForURL(u *url.URL) string {
|
|
filepath := strings.TrimPrefix(strings.TrimSuffix(u.Path, ".html"), "/")
|
|
if filepath == "" {
|
|
// "/" maps to "/home"
|
|
filepath = "home"
|
|
}
|
|
|
|
return filepath
|
|
}
|
|
|
|
type URLCalculator struct {
|
|
url *url.URL
|
|
}
|
|
|
|
func newURLCalculator(u *url.URL) URLCalculator {
|
|
cpy := *u
|
|
return URLCalculator{
|
|
url: &cpy,
|
|
}
|
|
}
|
|
|
|
func (c URLCalculator) SetQueryParam(k string, v any) string {
|
|
u := *c.url
|
|
q := u.Query()
|
|
q.Set(k, fmt.Sprint(v))
|
|
u.RawQuery = q.Encode()
|
|
|
|
return u.String()
|
|
}
|