package fw import ( "fmt" "github.com/CloudyKit/jet/v6" "net/http" ) type Response interface { Render() Error WriteHeader(statusCode int) } type ResponseFactory struct { writer http.ResponseWriter template *JetTemplate GetView func() any } func NewResponseFactory(writer http.ResponseWriter, template *JetTemplate, getView func() any) *ResponseFactory { return &ResponseFactory{ writer: writer, template: template, GetView: getView, } } func (it *ResponseFactory) String(str string) *StringResponse { return NewStringResponse(it.writer, str) } func (it *ResponseFactory) HtmlError(code int, message string) *HtmlErrorResponse { return NewHtmlErrorResponse(it.makeJetRender(), code, message) } func (it *ResponseFactory) View(template string, data any) *ViewResponse { return NewViewResponse(it.makeJetRender(), template, data) } func (it *ResponseFactory) makeJetRender() *JetRender { variables := make(jet.VarMap) if it.GetView != nil { variables.Set("vi", it.GetView()) } return NewJetRender(it.template, it.writer, variables) } type BaseResponse struct { statusCode int } func (it *BaseResponse) WriteHeader(statusCode int) { it.statusCode = statusCode } type StringResponse struct { BaseResponse str string writer http.ResponseWriter } func NewStringResponse(writer http.ResponseWriter, str string) *StringResponse { return &StringResponse{ writer: writer, str: str, } } func (it *StringResponse) Render() Error { it.writer.WriteHeader(it.statusCode) _, err := it.writer.Write([]byte(it.str)) if err != nil { return Err(err) } return nil } type HtmlErrorResponse struct { ViewResponse statusCode int message string } func NewHtmlErrorResponse(render *JetRender, code int, message string) *HtmlErrorResponse { return &HtmlErrorResponse{ ViewResponse: *NewViewResponse(render, "errors/error.html", nil), statusCode: code, message: message, } } func (it *HtmlErrorResponse) Render() Error { fmt.Println("status", it.statusCode) it.render.Writer.WriteHeader(it.statusCode) err := it.render.Render(it.template, map[string]any{ "title": fmt.Sprintf("%d %s", it.statusCode, http.StatusText(it.statusCode)), "message": it.message, }) if err != nil { return err.Tap() } return nil } type ViewResponse struct { BaseResponse render *JetRender template string data any } func NewViewResponse(render *JetRender, template string, data any) *ViewResponse { return &ViewResponse{ render: render, template: template, data: data, } } func (it *ViewResponse) Set(key string, value interface{}) *ViewResponse { it.render.Variables.Set(key, value) return it } func (it *ViewResponse) Render() Error { it.render.Writer.WriteHeader(it.statusCode) err := it.render.Render(it.template, it.data) if err != nil { return err.Tap() } return nil }