Defer setting headers to renderTemplate to avoid wasting resources for JSON requests and for future optimisations.

Error pages now use routes.renderTemplate bringing them in line with the other standard routes.
Every route should use a renderTemplate function now instead of calling RunTmpl.
Merged some pi and renderTemplate lines in routes to reduce the amount of vertical space used.
This commit is contained in:
Azareal 2019-04-19 19:34:16 +10:00
parent b487ad0e5a
commit 42b9f27c45
9 changed files with 47 additions and 73 deletions

View File

@ -129,7 +129,6 @@ func errorHeader(w http.ResponseWriter, user User, title string) *Header {
header := DefaultHeader(w, user) header := DefaultHeader(w, user)
header.Title = title header.Title = title
header.Zone = "error" header.Zone = "error"
prepResources(&user, header, header.Theme)
return header return header
} }
@ -304,10 +303,7 @@ func LoginRequiredJS(w http.ResponseWriter, r *http.Request, user User) RouteErr
func SecurityError(w http.ResponseWriter, r *http.Request, user User) RouteError { func SecurityError(w http.ResponseWriter, r *http.Request, user User) RouteError {
w.WriteHeader(403) w.WriteHeader(403)
pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("security_error_title")), phrases.GetErrorPhrase("security_error_body")} pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("security_error_title")), phrases.GetErrorPhrase("security_error_body")}
if RunPreRenderHook("pre_render_security_error", w, r, &user, &pi) { err := RenderTemplateAlias("error", "security_error", w, r, pi.Header, pi)
return nil
}
err := pi.Header.Theme.RunTmpl("error", pi, w)
if err != nil { if err != nil {
LogError(err) LogError(err)
} }
@ -381,12 +377,11 @@ func writeJsonError(errmsg string, w http.ResponseWriter) {
} }
func handleErrorTemplate(w http.ResponseWriter, r *http.Request, pi ErrorPage) { func handleErrorTemplate(w http.ResponseWriter, r *http.Request, pi ErrorPage) {
// TODO: What to do about this hook? err := RenderTemplateAlias("error", "error", w, r, pi.Header, pi)
if RunPreRenderHook("pre_render_error", w, r, &pi.Header.CurrentUser, &pi) {
return
}
err := pi.Header.Theme.RunTmpl("error", pi, w)
if err != nil { if err != nil {
LogError(err) LogError(err)
} }
} }
// Alias of routes.renderTemplate
var RenderTemplateAlias func(tmplName string, hookName string, w http.ResponseWriter, r *http.Request, header *Header, pi interface{}) error

View File

@ -222,11 +222,11 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Head
header.StartedAt = time.Now() header.StartedAt = time.Now()
} }
prepResources(user,header,theme) //PrepResources(user,header,theme)
return header, nil return header, nil
} }
func prepResources(user *User, header *Header, theme *Theme) { func PrepResources(user *User, header *Header, theme *Theme) {
header.AddSheet(theme.Name + "/main.css") header.AddSheet(theme.Name + "/main.css")
if len(theme.Resources) > 0 { if len(theme.Resources) > 0 {

View File

@ -11,6 +11,7 @@ import (
"strings" "strings"
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/routes"
) )
// A blank list to fill out that parameter in Page for routes which don't use it // A blank list to fill out that parameter in Page for routes which don't use it
@ -189,11 +190,7 @@ func RouteGuildList(w http.ResponseWriter, r *http.Request, user c.User) c.Route
} }
pi := ListPage{"Guild List", user, header, guildList} pi := ListPage{"Guild List", user, header, guildList}
err = header.Theme.RunTmpl("guilds_guild_list", pi, w) return routes.RenderTemplate("guilds_guild_list", w, r, header, pi)
if err != nil {
return c.InternalError(err, w, r)
}
return nil
} }
func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
@ -231,12 +228,7 @@ func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user c.User) c.Rou
} }
CommonAreaWidgets(header) CommonAreaWidgets(header)
pi := c.Page{header, tList, nil} return routes.RenderTemplate("guilds_create_guild", w, r, header, c.Page{header, tList, nil})
err := header.Theme.RunTmpl("guilds_create_guild", pi, w)
if err != nil {
return c.InternalError(err, w, r)
}
return nil
} }
func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
@ -384,7 +376,7 @@ func PreRenderViewForum(w http.ResponseWriter, r *http.Request, user *c.User, da
guildItem := guildData.(*Guild) guildItem := guildData.(*Guild)
guildpi := Page{pi.Title, pi.Header, pi.ItemList, pi.Forum, guildItem, pi.Page, pi.LastPage} guildpi := Page{pi.Title, pi.Header, pi.ItemList, pi.Forum, guildItem, pi.Page, pi.LastPage}
err := header.Theme.RunTmpl("guilds_view_guild", guildpi, w) err := routes.RenderTemplate("guilds_view_guild", w, r, header, guildpi)
if err != nil { if err != nil {
c.LogError(err) c.LogError(err)
return false return false

View File

@ -27,6 +27,7 @@ import (
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters" "github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/routes"
"github.com/Azareal/Gosora/query_gen" "github.com/Azareal/Gosora/query_gen"
"github.com/fsnotify/fsnotify" "github.com/fsnotify/fsnotify"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -41,6 +42,11 @@ type Globs struct {
stmts *Stmts stmts *Stmts
} }
// Temporary alias for renderTemplate
func init() {
c.RenderTemplateAlias = routes.RenderTemplate
}
// Experimenting with a new error package here to try to reduce the amount of debugging we have to do // Experimenting with a new error package here to try to reduce the amount of debugging we have to do
// TODO: Dynamically register these items to avoid maintaining as much code here? // TODO: Dynamically register these items to avoid maintaining as much code here?
func afterDBInit() (err error) { func afterDBInit() (err error) {

View File

@ -28,8 +28,7 @@ func AccountLogin(w http.ResponseWriter, r *http.Request, user c.User, header *c
return c.LocalError("You're already logged in.", w, r, user) return c.LocalError("You're already logged in.", w, r, user)
} }
header.Title = phrases.GetTitlePhrase("login") header.Title = phrases.GetTitlePhrase("login")
pi := c.Page{header, tList, nil} return renderTemplate("login", w, r, header, c.Page{header, tList, nil})
return renderTemplate("login", w, r, header, pi)
} }
// TODO: Log failed attempted logins? // TODO: Log failed attempted logins?
@ -160,16 +159,8 @@ func AccountLoginMFAVerify(w http.ResponseWriter, r *http.Request, user c.User,
if !mfaVerifySession(provSession, signedSession, uid) { if !mfaVerifySession(provSession, signedSession, uid) {
return c.LocalError("Invalid session", w, r, user) return c.LocalError("Invalid session", w, r, user)
} }
pi := c.Page{header, tList, nil} return renderTemplate("login_mfa_verify", w, r, header, c.Page{header, tList, nil})
if c.RunPreRenderHook("pre_render_login_mfa_verify", w, r, &user, &pi) {
return nil
}
err = header.Theme.RunTmpl("login_mfa_verify", pi, w)
if err != nil {
return c.InternalError(err, w, r)
}
return nil
} }
func AccountLoginMFAVerifySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountLoginMFAVerifySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
@ -202,8 +193,7 @@ func AccountRegister(w http.ResponseWriter, r *http.Request, user c.User, header
} }
header.Title = phrases.GetTitlePhrase("register") header.Title = phrases.GetTitlePhrase("register")
header.LooseCSP = true header.LooseCSP = true
pi := c.Page{header, tList, nil} return renderTemplate("register", w, r, header, c.Page{header, tList, nil})
return renderTemplate("register", w, r, header, pi)
} }
func isNumeric(data string) (numeric bool) { func isNumeric(data string) (numeric bool) {
@ -392,8 +382,7 @@ func AccountEdit(w http.ResponseWriter, r *http.Request, user c.User, header *c.
//edit_password //edit_password
func AccountEditPassword(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError { func AccountEditPassword(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
accountEditHead("account_password", w, r, &user, header) accountEditHead("account_password", w, r, &user, header)
pi := c.Page{header, tList, nil} return renderTemplate("account_own_edit_password", w, r, header, c.Page{header, tList, nil})
return renderTemplate("account_own_edit_password", w, r, header, pi)
} }
// TODO: Require re-authentication if the user hasn't logged in in a while // TODO: Require re-authentication if the user hasn't logged in in a while
@ -759,8 +748,7 @@ func LevelList(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
levels[i] = c.LevelListItem{i, iScore, status, perc * 2} levels[i] = c.LevelListItem{i, iScore, status, perc * 2}
} }
pi := c.LevelListPage{header, levels[1:]} return renderTemplate("level_list", w, r, header, c.LevelListPage{header, levels[1:]})
return renderTemplate("level_list", w, r, header, pi)
} }
func Alerts(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError { func Alerts(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {

View File

@ -76,6 +76,20 @@ func doPush(w http.ResponseWriter, header *c.Header) {
} }
func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) c.RouteError { func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) c.RouteError {
return renderTemplate2(tmplName, tmplName, w, r, header, pi)
}
func renderTemplate2(tmplName string, hookName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) c.RouteError {
err := renderTemplate3(tmplName, tmplName, w, r, header, pi)
if err != nil {
return c.InternalError(err, w, r)
}
return nil
}
func renderTemplate3(tmplName string, hookName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) error {
c.PrepResources(&header.CurrentUser, header, header.Theme)
if header.CurrentUser.Loggedin { if header.CurrentUser.Loggedin {
header.MetaDesc = "" header.MetaDesc = ""
header.OGDesc = "" header.OGDesc = ""
@ -98,12 +112,11 @@ func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, hea
if header.CurrentUser.IsAdmin { if header.CurrentUser.IsAdmin {
header.Elapsed1 = time.Since(header.StartedAt).String() header.Elapsed1 = time.Since(header.StartedAt).String()
} }
if c.RunPreRenderHook("pre_render_"+tmplName, w, r, &header.CurrentUser, pi) { if c.RunPreRenderHook("pre_render_"+hookName, w, r, &header.CurrentUser, pi) {
return nil return nil
} }
err := header.Theme.RunTmpl(tmplName, pi, w) return header.Theme.RunTmpl(tmplName, pi, w)
if err != nil {
return c.InternalError(err, w, r)
}
return nil
} }
// TODO: Rename renderTemplate to RenderTemplate instead of using this hack to avoid breaking things
var RenderTemplate = renderTemplate3

View File

@ -49,6 +49,5 @@ func ForumList(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
} }
} }
pi := c.ForumsPage{header, forumList} return renderTemplate("forums", w, r, header, c.ForumsPage{header, forumList})
return renderTemplate("forums", w, r, header, pi)
} }

View File

@ -50,8 +50,7 @@ func StaticFile(w http.ResponseWriter, r *http.Request) {
func Overview(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError { func Overview(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
header.Title = phrases.GetTitlePhrase("overview") header.Title = phrases.GetTitlePhrase("overview")
header.Zone = "overview" header.Zone = "overview"
pi := c.Page{header, tList, nil} return renderTemplate("overview", w, r, header, c.Page{header, tList, nil})
return renderTemplate("overview", w, r, header, pi)
} }
func CustomPage(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header, name string) c.RouteError { func CustomPage(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header, name string) c.RouteError {
@ -60,8 +59,7 @@ func CustomPage(w http.ResponseWriter, r *http.Request, user c.User, header *c.H
page, err := c.Pages.GetByName(name) page, err := c.Pages.GetByName(name)
if err == nil { if err == nil {
header.Title = page.Title header.Title = page.Title
pi := c.CustomPagePage{header, page} return renderTemplate("custom_page", w, r, header, c.CustomPagePage{header, page})
return renderTemplate("custom_page", w, r, header, pi)
} else if err != sql.ErrNoRows { } else if err != sql.ErrNoRows {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
@ -72,16 +70,8 @@ func CustomPage(w http.ResponseWriter, r *http.Request, user c.User, header *c.H
} }
header.Title = phrases.GetTitlePhrase("page") header.Title = phrases.GetTitlePhrase("page")
pi := c.Page{header, tList, nil}
// TODO: Pass the page name to the pre-render hook? // TODO: Pass the page name to the pre-render hook?
if c.RunPreRenderHook("pre_render_tmpl_page", w, r, &user, &pi) { return renderTemplate2("page_"+name, "tmpl_page", w, r, header, c.Page{header, tList, nil})
return nil
}
err = header.Theme.RunTmpl("page_"+name, pi, w)
if err != nil {
return c.InternalError(err, w, r)
}
return nil
} }
// TODO: Set the cookie domain // TODO: Set the cookie domain

View File

@ -26,14 +26,5 @@ func IPSearch(w http.ResponseWriter, r *http.Request, user c.User, header *c.Hea
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
return renderTemplate("ip_search", w, r, header, c.IPSearchPage{header, userList, ip})
pi := c.IPSearchPage{header, userList, ip}
if c.RunPreRenderHook("pre_render_ip_search", w, r, &user, &pi) {
return nil
}
err = header.Theme.RunTmpl("ip_search", pi, w)
if err != nil {
return c.InternalError(err, w, r)
}
return nil
} }