From db1a896260c5a14e6b8b3744443877108ba86589 Mon Sep 17 00:00:00 2001 From: Hans Date: Thu, 19 Sep 2024 21:26:27 +0200 Subject: [PATCH] feat: only send fragments when using unpoly --- handlehttp/cors.go | 6 +-- handlehttp/handler-types.go | 10 ++--- handlehttp/html-mapper.go | 11 +++-- handlehttp/match-accept.go | 14 +++--- handlerUtil.go | 19 +++++--- html-frontend/base-templates/fragment.gohtml | 5 +++ .../base-templates/page-layout.gohtml | 44 +++++++++---------- html-frontend/static/style.css | 1 - 8 files changed, 60 insertions(+), 50 deletions(-) create mode 100644 html-frontend/base-templates/fragment.gohtml diff --git a/handlehttp/cors.go b/handlehttp/cors.go index 2ef3a95..3c0c78a 100644 --- a/handlehttp/cors.go +++ b/handlehttp/cors.go @@ -10,13 +10,13 @@ type CorsConfig struct { } func AddCorsHeader(config CorsConfig, next GetResponseMapper) GetResponseMapper { - return func(r *http.Request) *ResponseMapper { + return func(r *http.Request) ResponseMapper { mapper := next(r) var newMapper ResponseMapper = func(w http.ResponseWriter, status int, data any) { setCorsHeaders(w, config) - (*mapper)(w, status, data) + mapper(w, status, data) } - return &newMapper + return newMapper } } diff --git a/handlehttp/handler-types.go b/handlehttp/handler-types.go index 5d15275..1994c6f 100644 --- a/handlehttp/handler-types.go +++ b/handlehttp/handler-types.go @@ -7,10 +7,10 @@ import ( type RequestResponseHandler func(w http.ResponseWriter, r *http.Request) type RequestHandler func(r *http.Request) (status int, result any) type ResponseMapper func(w http.ResponseWriter, status int, data any) -type GetResponseMapper func(r *http.Request) *ResponseMapper +type GetResponseMapper func(r *http.Request) ResponseMapper func AlwaysMapWith(mapper ResponseMapper) GetResponseMapper { - return func(r *http.Request) *ResponseMapper { return &mapper } + return func(r *http.Request) ResponseMapper { return mapper } } // Get a RequestResponseHandler by mapping the result of the RequestHandler using the ResponseMapper @@ -23,11 +23,7 @@ func MappingResultOf(handler RequestHandler, getMapper GetResponseMapper) Reques return func(w http.ResponseWriter, r *http.Request) { mapper := getMapper(r) - if mapper == nil || *mapper == nil { - w.WriteHeader(http.StatusNotFound) - return - } status, result := (handler)(r) - (*mapper)(w, status, result) + (mapper)(w, status, result) } } diff --git a/handlehttp/html-mapper.go b/handlehttp/html-mapper.go index 9b468eb..dcd7765 100644 --- a/handlehttp/html-mapper.go +++ b/handlehttp/html-mapper.go @@ -7,14 +7,19 @@ import ( "net/http" ) -func HtmlMapper(tplFS fs.FS, tplPaths ...string) ResponseMapper { - templates := append(tplPaths, "base-templates/page-layout.gohtml") +func HtmlMapper(tplFS fs.FS, useFragment bool, tplPaths ...string) ResponseMapper { + templates := append(tplPaths, "base-templates/page-layout.gohtml", "base-templates/fragment.gohtml") tpl := template.Must(template.ParseFS(tplFS, templates...)) return func(w http.ResponseWriter, status int, data any) { w.Header().Set("content-type", Html.String()) w.WriteHeader(status) - err := executeWholePageTemplate(w, tpl, data) + var err error + if useFragment { + err = executeFragmentTemplate(w, tpl, data) + } else { + err = executeWholePageTemplate(w, tpl, data) + } if err != nil { log.Println("Error while writing html response:", err) diff --git a/handlehttp/match-accept.go b/handlehttp/match-accept.go index a5528a2..b90dadf 100644 --- a/handlehttp/match-accept.go +++ b/handlehttp/match-accept.go @@ -1,6 +1,7 @@ package handlehttp import ( + "log" "net/http" contenttype "github.com/Port39/go-drink/handlehttp/content-type" @@ -28,22 +29,23 @@ var AllowedMediaTypes = []contenttype.MediaType{ } // Match the most appropriate choice in elementsByAccept based on the request's accept header -func MatchByAcceptHeader[T any](elementsByAccept ByAccept[T]) func(r *http.Request) *T { - return func(r *http.Request) *T { +func MatchByAcceptHeader[T any](elementsByAccept ByAccept[T], defaultElement T) func(r *http.Request) T { + return func(r *http.Request) T { result, _, err := contenttype.GetAcceptableMediaTypeFromHeader(r.Header.Get("Accept"), AllowedMediaTypes) if err != nil { - return nil + log.Println("Accept header", r.Header.Get("Accept"), "=>", result, err) + return defaultElement } if Html.Equal(result) { - return &elementsByAccept.Html + return elementsByAccept.Html } if Json.Equal(result) { - return &elementsByAccept.Json + return elementsByAccept.Json } - return nil + return defaultElement } } diff --git a/handlerUtil.go b/handlerUtil.go index b85ad6a..c12a40b 100644 --- a/handlerUtil.go +++ b/handlerUtil.go @@ -77,16 +77,21 @@ func getHtmlTemplates() fs.FS { var htmlTemplates fs.FS = getHtmlTemplates() func toJsonOrHtmlByAccept(htmlPath string) handlehttp.GetResponseMapper { - return handlehttp.MatchByAcceptHeader( - handlehttp.ByAccept[handlehttp.ResponseMapper]{ - Json: handlehttp.JsonMapper, - Html: handlehttp.HtmlMapper(htmlTemplates, htmlPath), - }, - ) + return func(r *http.Request) handlehttp.ResponseMapper { + mappersByAccept := handlehttp.ByAccept[handlehttp.GetResponseMapper]{ + Json: handlehttp.AlwaysMapWith(handlehttp.JsonMapper), + Html: toHtml(htmlPath), + } + responseMapper := handlehttp.MatchByAcceptHeader(mappersByAccept, mappersByAccept.Json)(r) + return responseMapper(r) + } } func toHtml(htmlPath string) handlehttp.GetResponseMapper { - return handlehttp.AlwaysMapWith(handlehttp.HtmlMapper(htmlTemplates, htmlPath)) + return func(r *http.Request) handlehttp.ResponseMapper { + isUnpolyRequest := r.Header.Get("X-Up-Version") != "" + return handlehttp.HtmlMapper(htmlTemplates, isUnpolyRequest, htmlPath) + } } //go:embed html-frontend/static/* diff --git a/html-frontend/base-templates/fragment.gohtml b/html-frontend/base-templates/fragment.gohtml new file mode 100644 index 0000000..e928ca2 --- /dev/null +++ b/html-frontend/base-templates/fragment.gohtml @@ -0,0 +1,5 @@ +{{define "fragment"}} +
+ {{template "content" .}} +
+{{end}} \ No newline at end of file diff --git a/html-frontend/base-templates/page-layout.gohtml b/html-frontend/base-templates/page-layout.gohtml index 7b767e0..efbdc2a 100644 --- a/html-frontend/base-templates/page-layout.gohtml +++ b/html-frontend/base-templates/page-layout.gohtml @@ -1,24 +1,24 @@ {{ define "base" }} - - + + - - - - {{template "title"}} - - - - - - - + + + + {{template "title"}} + + + + + + + - +
-
- {{ template "content" . }} -
+ {{ template "fragment" . }} - + - + {{end}} diff --git a/html-frontend/static/style.css b/html-frontend/static/style.css index b6beaa9..27578fa 100644 --- a/html-frontend/static/style.css +++ b/html-frontend/static/style.css @@ -8,5 +8,4 @@ --breakpoint-lg: 992px; --breakpoint-xl: 1200px; --breakpoint-xxl: 1400px; - }