146 lines
3.5 KiB
Go
146 lines
3.5 KiB
Go
package ersteller_lib
|
|
|
|
import (
|
|
"maragu.dev/gomponents"
|
|
htmx "maragu.dev/gomponents-htmx"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
type HtmxContext interface {
|
|
Render(node gomponents.Node)
|
|
SetError(err error)
|
|
GetLanguage() Language
|
|
GetActivePath() *ActivePath
|
|
HasActivePath() bool
|
|
SetActivePath(activePath *ActivePath)
|
|
GetPath() string
|
|
GetPathParam(key string, defaultValue ...string) string
|
|
}
|
|
|
|
type HtmxContextImpl struct {
|
|
req *http.Request
|
|
res http.ResponseWriter
|
|
language Language
|
|
activePath *ActivePath
|
|
}
|
|
|
|
func (c *HtmxContextImpl) SetError(err error) {
|
|
_, writeErr := c.res.Write([]byte(err.Error()))
|
|
if writeErr != nil {
|
|
Error("failed to write error", writeErr)
|
|
}
|
|
c.res.WriteHeader(500)
|
|
}
|
|
|
|
func (c *HtmxContextImpl) GetPathParam(key string, defaultValue ...string) string {
|
|
pathParam := c.req.PathValue(key)
|
|
if pathParam != "" {
|
|
return pathParam
|
|
}
|
|
if len(defaultValue) > 0 {
|
|
return defaultValue[0]
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (c *HtmxContextImpl) GetPath() string {
|
|
return c.req.URL.Path
|
|
}
|
|
|
|
func (c *HtmxContextImpl) SetActivePath(activePath *ActivePath) {
|
|
c.activePath = activePath
|
|
}
|
|
|
|
func (c *HtmxContextImpl) GetActivePath() *ActivePath {
|
|
return c.activePath
|
|
}
|
|
|
|
func (c *HtmxContextImpl) HasActivePath() bool {
|
|
return c.activePath != nil
|
|
}
|
|
|
|
func (c *HtmxContextImpl) GetLanguage() Language {
|
|
return c.language
|
|
}
|
|
|
|
func NewHtmxContext(req *http.Request, res http.ResponseWriter, language Language) HtmxContext {
|
|
return &HtmxContextImpl{req: req, res: res, language: language}
|
|
}
|
|
|
|
func (c *HtmxContextImpl) Render(node gomponents.Node) {
|
|
err := node.Render(c.res)
|
|
if err != nil {
|
|
Error("failed to render", err)
|
|
c.SetError(err)
|
|
}
|
|
}
|
|
|
|
type HtmxRouteFunc func(ctx HtmxContext)
|
|
|
|
type HtmxPathParam struct {
|
|
Key string
|
|
Value string
|
|
}
|
|
|
|
type HtmxRoute interface {
|
|
WithPathParams(params ...HtmxPathParam) HtmxRoute
|
|
ToUrl(language Language, queryParams ...HtmxPathParam) string
|
|
GetHtmx(language Language, queryParams ...HtmxPathParam) gomponents.Node
|
|
SetActivePath(activePath *ActivePath) HtmxRoute
|
|
Add(server *http.ServeMux)
|
|
}
|
|
|
|
func addLanguageToPath(path string, language Language) string {
|
|
return "/" + string(language) + path
|
|
}
|
|
|
|
type HtmxGetRoute struct {
|
|
Path string
|
|
RouteFunc HtmxRouteFunc
|
|
PathParams []HtmxPathParam
|
|
Languages []Language
|
|
ActivePath *ActivePath
|
|
}
|
|
|
|
func (h HtmxGetRoute) SetActivePath(activePath *ActivePath) HtmxRoute {
|
|
h.ActivePath = activePath
|
|
return h
|
|
}
|
|
|
|
func NewHtmxGetRoute(path string, routeFunc HtmxRouteFunc, languages ...Language) *HtmxGetRoute {
|
|
return &HtmxGetRoute{Path: path, RouteFunc: routeFunc, Languages: languages}
|
|
}
|
|
|
|
func (h HtmxGetRoute) Add(server *http.ServeMux) {
|
|
for _, language := range h.Languages {
|
|
server.HandleFunc("GET "+addLanguageToPath(h.Path, language), func(res http.ResponseWriter, req *http.Request) {
|
|
context := NewHtmxContext(req, res, language)
|
|
if h.ActivePath != nil {
|
|
context.SetActivePath(h.ActivePath)
|
|
}
|
|
h.RouteFunc(context)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (h HtmxGetRoute) WithPathParams(params ...HtmxPathParam) HtmxRoute {
|
|
h.PathParams = params
|
|
return h
|
|
}
|
|
|
|
func (h HtmxGetRoute) ToUrl(language Language, queryParams ...HtmxPathParam) string {
|
|
if len(h.PathParams) == 0 {
|
|
return h.Path
|
|
}
|
|
path := addLanguageToPath(h.Path, language)
|
|
for _, param := range h.PathParams {
|
|
path = strings.ReplaceAll(path, "{"+param.Key+"}", param.Value)
|
|
}
|
|
return path
|
|
}
|
|
|
|
func (h HtmxGetRoute) GetHtmx(language Language, queryParams ...HtmxPathParam) gomponents.Node {
|
|
return htmx.Get(h.ToUrl(language, queryParams...))
|
|
}
|