go: implement the Echo renderer for templates
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
leo 2023-05-06 21:50:35 +02:00
parent e651235f90
commit 9dbc475145
Signed by: wanderer
SSH Key Fingerprint: SHA256:Dp8+iwKHSlrMEHzE3bJnPng70I7LEsa3IJXRH/U+idQ
4 changed files with 61 additions and 87 deletions

@ -16,6 +16,7 @@ func (a *App) SetupRoutes() {
// run this before declaring any handler funcs.
handlers.InitHandlers(setting, tmpls)
e.Renderer = handlers.Renderer
// keep /static/* as a compatibility fallback for /assets.
e.GET(

@ -23,7 +23,7 @@ type tplMap map[string]*template.Template
var (
// tmpl *template.Template.
tmpls = template.New("")
// tmpls = template.New("").
templateMap tplMap
tmplFS fs.FS
bluemondayPolicy = bluemonday.UGCPolicy()
@ -65,13 +65,13 @@ func initTemplates(f fs.FS) {
tmplFS = f
}
setFuncMap(tmpls)
setFuncMap(Renderer.tmpls)
allTmpls := listAllTmpls()
// ensure this fails at compile time, if at all ("Must").
tmpls = template.Must(tmpls.ParseFS(tmplFS, allTmpls...))
makeTplMap(tmpls)
Renderer.tmpls = template.Must(Renderer.tmpls.ParseFS(tmplFS, allTmpls...))
makeTplMap(Renderer.tmpls)
}
func makeTplMap(tpl *template.Template) {
@ -105,10 +105,10 @@ func getTmpl(name string) *template.Template {
allTmpls := listAllTmpls()
// ensure this fails at compile time, if at all ("Must").
tmpls = template.Must(tpl.ParseFS(tmplFS, allTmpls...))
Renderer.tmpls = template.Must(tpl.ParseFS(tmplFS, allTmpls...))
}
return tmpls.Lookup(name)
return Renderer.tmpls.Lookup(name)
}
func Admin() echo.HandlerFunc {
@ -157,9 +157,9 @@ func Signin() echo.HandlerFunc {
return c.Redirect(http.StatusFound, "/home")
}
tpl := getTmpl("signin.tmpl")
err := tpl.Execute(c.Response().Writer,
return c.Render(
http.StatusOK,
"signin.tmpl",
page{
AppName: setting.AppName(),
AppVer: appver,
@ -168,11 +168,6 @@ func Signin() echo.HandlerFunc {
Current: "signin",
},
)
if err != nil {
return err
}
return nil
}
}
@ -246,16 +241,12 @@ func SigninPost(client *ent.Client) echo.HandlerFunc {
if err != nil {
c.Logger().Error("failed to save session")
err = renderErrorPage(
c.Response().Writer,
return renderErrorPage(
c,
http.StatusInternalServerError,
http.StatusText(http.StatusInternalServerError)+" (make sure you've got cookies enabled)",
err.Error(),
)
if err != nil {
return err
}
}
}
@ -275,8 +266,6 @@ func Signup() echo.HandlerFunc {
}
}
tpl := getTmpl("signup.tmpl")
csrf := c.Get("csrf").(string)
// secure := c.Request().URL.Scheme == "https"
@ -291,7 +280,9 @@ func Signup() echo.HandlerFunc {
// }
// c.SetCookie(cookieCSRF)
err := tpl.Execute(c.Response().Writer,
err := c.Render(
http.StatusOK,
"signup.tmpl",
page{
AppName: setting.AppName(),
AppVer: appver,
@ -304,16 +295,12 @@ func Signup() echo.HandlerFunc {
if err != nil {
log.Warnf("error: %q", err)
err = renderErrorPage(
c.Response().Writer,
return renderErrorPage(
c,
http.StatusInternalServerError,
http.StatusText(http.StatusInternalServerError),
err.Error(),
)
if err != nil {
return err
}
}
return nil
@ -360,7 +347,7 @@ func SignupPost(client *ent.Client) echo.HandlerFunc {
c.Logger().Error("error checking whether user exists", err)
return renderErrorPage(
c.Response().Writer,
c,
http.StatusInternalServerError,
http.StatusText(http.StatusInternalServerError),
err.Error(),
@ -387,18 +374,13 @@ func SignupPost(client *ent.Client) echo.HandlerFunc {
// stating what went wrong.
return c.Redirect(http.StatusSeeOther, "/signup")
}
// TODO: don't return the error to the user, perhaps based
// on the devel mode.
err = renderErrorPage(
c.Response().Writer,
return renderErrorPage(
c,
http.StatusInternalServerError,
http.StatusText(http.StatusInternalServerError)+" - failed to create schema resources",
err.Error(),
)
if err != nil {
c.Logger().Error("error: %q", err)
return err
}
}
log.Infof("successfully registered user '%s'", username)
@ -421,16 +403,12 @@ func SignupPost(client *ent.Client) echo.HandlerFunc {
if err != nil {
c.Logger().Error("failed to save session")
err = renderErrorPage(
c.Response().Writer,
return renderErrorPage(
c,
http.StatusInternalServerError,
http.StatusText(http.StatusInternalServerError)+" (make sure you've got cookies enabled)",
err.Error(),
)
if err != nil {
return err
}
}
return c.Redirect(http.StatusMovedPermanently, "/home")
@ -441,8 +419,6 @@ func Home(client *ent.Client) echo.HandlerFunc {
return func(c echo.Context) error {
var username string
tpl := getTmpl("home.tmpl")
sess, _ := session.Get(setting.SessionCookieName(), c)
if sess == nil {
log.Info("no session, redirecting to /signin", "endpoint", "/home")
@ -483,20 +459,15 @@ func Home(client *ent.Client) echo.HandlerFunc {
} else {
c.Logger().Error("failed to query usr", username)
err = renderErrorPage(
c.Response().Writer,
return renderErrorPage(
c,
http.StatusInternalServerError,
http.StatusText(http.StatusInternalServerError)+" failed to query usr (make sure you've got cookies enabled)",
err.Error(),
)
if err != nil {
return err
}
return err
}
err := tpl.Execute(c.Response().Writer,
err := c.Render(http.StatusInternalServerError, "home.tmpl",
page{
AppName: setting.AppName(),
AppVer: appver,
@ -508,24 +479,13 @@ func Home(client *ent.Client) echo.HandlerFunc {
},
)
if err != nil {
log.Warnf("error: %q", err)
c.Logger().Errorf("error: %q", err)
err = renderErrorPage(
c.Response().Writer,
return renderErrorPage(
c,
http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError),
err.Error(),
)
if err != nil {
c.Logger().Errorf("error: %q", err)
return echo.NewHTTPError(
http.StatusInternalServerError,
http.StatusText(http.StatusInternalServerError),
)
}
}
return nil
@ -554,9 +514,9 @@ func Logout() echo.HandlerFunc {
return c.Redirect(http.StatusMovedPermanently, "/logout")
case c.Request().Method == "GET":
tpl := getTmpl("logout.tmpl")
err := tpl.Execute(c.Response().Writer,
err := c.Render(
http.StatusOK,
"logout.tmpl",
page{
AppName: setting.AppName(),
AppVer: appver,
@ -568,18 +528,12 @@ func Logout() echo.HandlerFunc {
if err != nil {
c.Logger().Errorf("error: %q", err)
err = renderErrorPage(
c.Response().Writer,
return renderErrorPage(
c,
http.StatusInternalServerError,
http.StatusText(http.StatusInternalServerError),
err.Error(),
)
if err != nil {
c.Logger().Errorf("error: %q", err)
return err
}
}
}

@ -2,15 +2,17 @@ package handlers
import (
"fmt"
"io"
"strconv"
"github.com/labstack/echo/v4"
)
func renderErrorPage(wr io.Writer, status int, statusText, error string) error {
tpl := getTmpl("errorPage.tmpl")
func renderErrorPage(c echo.Context, status int, statusText, error string) error {
strStatus := strconv.Itoa(status)
err := tpl.Execute(wr,
return c.Render(
status,
"errorPage.tmpl",
page{
AppName: setting.AppName(),
AppVer: appver,
@ -22,9 +24,4 @@ func renderErrorPage(wr io.Writer, status int, statusText, error string) error {
StatusText: statusText,
},
)
if err != nil {
return err
}
return nil
}

22
handlers/templates.go Normal file

@ -0,0 +1,22 @@
package handlers
import (
"html/template"
"io"
"github.com/labstack/echo/v4"
)
type TemplateRenderer struct {
tmpls *template.Template
}
var Renderer = &TemplateRenderer{tmpls: template.New("")}
func (t *TemplateRenderer) Render(w io.Writer, name string, data any, c echo.Context) error {
c.Logger().Debugf("rendering template %s", name)
tpl := getTmpl(name)
return tpl.Execute(w, data)
}