133 lines
2.8 KiB
Go
133 lines
2.8 KiB
Go
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
|
|
}
|