Add ActivityMatches store impl.

Comment out errorBuffer.
Optimise LogWarning() with a string builder.
Avoid allocing byte slice in MicroNotFound()
Rename basePage to bp.
Reduce boilerplate.
This commit is contained in:
Azareal 2021-04-28 18:39:08 +10:00
parent 01a19ede79
commit 0c1f5cac94
5 changed files with 150 additions and 88 deletions

View File

@ -0,0 +1,54 @@
package common
import (
"database/sql"
qgen "github.com/Azareal/Gosora/query_gen"
)
var ActivityMatches ActivityStreamMatches
type ActivityStreamMatches interface {
Add(watcher, asid int) error
Delete(watcher, asid int) error
DeleteAndCountChanged(watcher, asid int) (int, error)
CountAsid(asid int) int
}
type DefaultActivityStreamMatches struct {
add *sql.Stmt
delete *sql.Stmt
countAsid *sql.Stmt
}
func NewDefaultActivityStreamMatches(acc *qgen.Accumulator) (*DefaultActivityStreamMatches, error) {
asm := "activity_stream_matches"
return &DefaultActivityStreamMatches{
add: acc.Insert(asm).Columns("watcher,asid").Fields("?,?").Prepare(),
delete: acc.Delete(asm).Where("watcher=? AND asid=?").Prepare(),
countAsid: acc.Count(asm).Where("asid=?").Prepare(),
}, acc.FirstError()
}
func (s *DefaultActivityStreamMatches) Add(watcher, asid int) error {
_, e := s.add.Exec(watcher, asid)
return e
}
func (s *DefaultActivityStreamMatches) Delete(watcher, asid int) error {
_, e := s.delete.Exec(watcher, asid)
return e
}
func (s *DefaultActivityStreamMatches) DeleteAndCountChanged(watcher, asid int) (int, error) {
res, e := s.delete.Exec(watcher, asid)
if e != nil {
return 0, e
}
c64, e := res.RowsAffected()
return int(c64), e
}
func (s *DefaultActivityStreamMatches) CountAsid(asid int) int {
return Countf(s.countAsid, asid)
}

View File

@ -7,8 +7,9 @@ import (
"runtime/debug"
"strings"
"sync"
"sync/atomic"
"github.com/Azareal/Gosora/common/phrases"
p "github.com/Azareal/Gosora/common/phrases"
)
type ErrorItem struct {
@ -20,7 +21,8 @@ type ErrorItem struct {
// TODO: Use the errorBuffer variable to construct the system log in the Control Panel. Should we log errors caused by users too? Or just collect statistics on those or do nothing? Intercept recover()? Could we intercept the logger instead here? We might get too much information, if we intercept the logger, maybe make it part of the Debug page?
// ? - Should we pass Header / HeaderLite rather than forcing the errors to pull the global Header instance?
var errorBufferMutex sync.RWMutex
var errorBuffer []ErrorItem
//var errorBuffer []ErrorItem
var ErrorCountSinceStartup int64
//var notfoundCountPerSecond int
//var nopermsCountPerSecond int
@ -110,24 +112,29 @@ func LogError(err error, extra ...string) {
}
func LogWarning(err error, extra ...string) {
var errmsg string
var esb strings.Builder
for _, extraBit := range extra {
errmsg += extraBit + "\n"
esb.WriteString(extraBit)
esb.WriteRune(10)
}
if err == nil {
errmsg += "nil error found"
esb.WriteString("nil error found")
} else {
errmsg += err.Error()
esb.WriteString(err.Error())
}
esb.WriteRune(10)
errmsg := esb.String()
errorBufferMutex.Lock()
defer errorBufferMutex.Unlock()
stack := debug.Stack() // debug.Stack() can't be executed concurrently, so we'll guard this with a mutex too
Err(errmsg+"\n", string(stack))
errorBuffer = append(errorBuffer, ErrorItem{err, stack})
Err(errmsg, string(stack))
//errorBuffer = append(errorBuffer, ErrorItem{err, stack})
atomic.AddInt64(&ErrorCountSinceStartup,1)
}
func errorHeader(w http.ResponseWriter, user *User, title string) *Header {
h := DefaultHeader(w, user)
func errorHeader(w http.ResponseWriter, u *User, title string) *Header {
h := DefaultHeader(w, u)
h.Title = title
h.Zone = "error"
return h
@ -138,7 +145,7 @@ func errorHeader(w http.ResponseWriter, user *User, title string) *Header {
// ? - Add a user parameter?
// ! Do not call CustomError here or we might get an error loop
func InternalError(err error, w http.ResponseWriter, r *http.Request) RouteError {
pi := ErrorPage{errorHeader(w, &GuestUser, phrases.GetErrorPhrase("internal_error_title")), phrases.GetErrorPhrase("internal_error_body")}
pi := ErrorPage{errorHeader(w, &GuestUser, p.GetErrorPhrase("internal_error_title")), p.GetErrorPhrase("internal_error_body")}
handleErrorTemplate(w, r, pi, 500)
LogError(err)
return HandledRouteError()
@ -157,14 +164,14 @@ func InternalErrorJSQ(err error, w http.ResponseWriter, r *http.Request, js bool
// ? - Add a user parameter?
func InternalErrorJS(err error, w http.ResponseWriter, r *http.Request) RouteError {
w.WriteHeader(500)
writeJsonError(phrases.GetErrorPhrase("internal_error_body"), w)
writeJsonError(p.GetErrorPhrase("internal_error_body"), w)
LogError(err)
return HandledRouteError()
}
// When the task system detects if the database is down, some database errors might slip by this
func DatabaseError(w http.ResponseWriter, r *http.Request) RouteError {
pi := ErrorPage{errorHeader(w, &GuestUser, phrases.GetErrorPhrase("internal_error_title")), phrases.GetErrorPhrase("internal_error_body")}
pi := ErrorPage{errorHeader(w, &GuestUser, p.GetErrorPhrase("internal_error_title")), p.GetErrorPhrase("internal_error_body")}
handleErrorTemplate(w, r, pi, 500)
return HandledRouteError()
}
@ -173,7 +180,7 @@ func InternalErrorXML(err error, w http.ResponseWriter, r *http.Request) RouteEr
w.Header().Set("Content-Type", "application/xml")
w.WriteHeader(500)
w.Write([]byte(`<?xml version="1.0"encoding="UTF-8"?>
<error>` + phrases.GetErrorPhrase("internal_error_body") + `</error>`))
<error>` + p.GetErrorPhrase("internal_error_body") + `</error>`))
LogError(err)
return HandledRouteError()
}
@ -183,14 +190,14 @@ func SilentInternalErrorXML(err error, w http.ResponseWriter, r *http.Request) R
w.Header().Set("Content-Type", "application/xml")
w.WriteHeader(500)
w.Write([]byte(`<?xml version="1.0"encoding="UTF-8"?>
<error>` + phrases.GetErrorPhrase("internal_error_body") + `</error>`))
<error>` + p.GetErrorPhrase("internal_error_body") + `</error>`))
log.Print("InternalError: ", err)
return HandledRouteError()
}
// ! Do not call CustomError here otherwise we might get an error loop
func PreError(errmsg string, w http.ResponseWriter, r *http.Request) RouteError {
pi := ErrorPage{errorHeader(w, &GuestUser, phrases.GetErrorPhrase("error_title")), errmsg}
pi := ErrorPage{errorHeader(w, &GuestUser, p.GetErrorPhrase("error_title")), errmsg}
handleErrorTemplate(w, r, pi, 500)
return HandledRouteError()
}
@ -212,33 +219,33 @@ func PreErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, js bool)
// TODO: Pass header in for this and similar errors instead of having to pass in both user and w? Would also allow for more stateful things, although this could be a problem
/*func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user *User) RouteError {
w.WriteHeader(500)
pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("local_error_title")), errmsg}
pi := ErrorPage{errorHeader(w, user, p.GetErrorPhrase("local_error_title")), errmsg}
handleErrorTemplate(w, r, pi)
return HandledRouteError()
}*/
func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user *User) RouteError {
return SimpleError(errmsg, w, r, errorHeader(w, user, ""))
func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, u *User) RouteError {
return SimpleError(errmsg, w, r, errorHeader(w, u, ""))
}
func LocalErrorf(errmsg string, w http.ResponseWriter, r *http.Request, user *User, params ...interface{}) RouteError {
return LocalError(fmt.Sprintf(errmsg, params), w, r, user)
func LocalErrorf(errmsg string, w http.ResponseWriter, r *http.Request, u *User, params ...interface{}) RouteError {
return LocalError(fmt.Sprintf(errmsg, params), w, r, u)
}
func SimpleError(errmsg string, w http.ResponseWriter, r *http.Request, h *Header) RouteError {
if h == nil {
h = errorHeader(w, &GuestUser, phrases.GetErrorPhrase("local_error_title"))
h = errorHeader(w, &GuestUser, p.GetErrorPhrase("local_error_title"))
} else {
h.Title = phrases.GetErrorPhrase("local_error_title")
h.Title = p.GetErrorPhrase("local_error_title")
}
pi := ErrorPage{h, errmsg}
handleErrorTemplate(w, r, pi, 500)
return HandledRouteError()
}
func LocalErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, user *User, js bool) RouteError {
func LocalErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, u *User, js bool) RouteError {
if !js {
return SimpleError(errmsg, w, r, errorHeader(w, user, ""))
return SimpleError(errmsg, w, r, errorHeader(w, u, ""))
}
return LocalErrorJS(errmsg, w, r)
}
@ -252,27 +259,27 @@ func LocalErrorJS(errmsg string, w http.ResponseWriter, r *http.Request) RouteEr
// TODO: We might want to centralise the error logic in the future and just return what the error handler needs to construct the response rather than handling it here
// NoPermissions is an error shown to the end-user when they try to access an area which they aren't authorised to access
func NoPermissions(w http.ResponseWriter, r *http.Request, u *User) RouteError {
pi := ErrorPage{errorHeader(w, u, phrases.GetErrorPhrase("no_permissions_title")), phrases.GetErrorPhrase("no_permissions_body")}
pi := ErrorPage{errorHeader(w, u, p.GetErrorPhrase("no_permissions_title")), p.GetErrorPhrase("no_permissions_body")}
handleErrorTemplate(w, r, pi, 403)
return HandledRouteError()
}
func NoPermissionsJSQ(w http.ResponseWriter, r *http.Request, user *User, js bool) RouteError {
func NoPermissionsJSQ(w http.ResponseWriter, r *http.Request, u *User, js bool) RouteError {
if !js {
return NoPermissions(w, r, user)
return NoPermissions(w, r, u)
}
return NoPermissionsJS(w, r, user)
return NoPermissionsJS(w, r, u)
}
func NoPermissionsJS(w http.ResponseWriter, r *http.Request, user *User) RouteError {
func NoPermissionsJS(w http.ResponseWriter, r *http.Request, u *User) RouteError {
w.WriteHeader(403)
writeJsonError(phrases.GetErrorPhrase("no_permissions_body"), w)
writeJsonError(p.GetErrorPhrase("no_permissions_body"), w)
return HandledRouteError()
}
// ? - Is this actually used? Should it be used? A ban in Gosora should be more of a permission revocation to stop them posting rather than something which spits up an error page, right?
func Banned(w http.ResponseWriter, r *http.Request, user *User) RouteError {
pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("banned_title")), phrases.GetErrorPhrase("banned_body")}
func Banned(w http.ResponseWriter, r *http.Request, u *User) RouteError {
pi := ErrorPage{errorHeader(w, u, p.GetErrorPhrase("banned_title")), p.GetErrorPhrase("banned_body")}
handleErrorTemplate(w, r, pi, 403)
return HandledRouteError()
}
@ -286,50 +293,51 @@ func BannedJSQ(w http.ResponseWriter, r *http.Request, user *User, js bool) Rout
return BannedJS(w, r, user)
}
func BannedJS(w http.ResponseWriter, r *http.Request, user *User) RouteError {
func BannedJS(w http.ResponseWriter, r *http.Request, u *User) RouteError {
w.WriteHeader(403)
writeJsonError(phrases.GetErrorPhrase("banned_body"), w)
writeJsonError(p.GetErrorPhrase("banned_body"), w)
return HandledRouteError()
}
// nolint
func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user *User, js bool) RouteError {
func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, u *User, js bool) RouteError {
if !js {
return LoginRequired(w, r, user)
return LoginRequired(w, r, u)
}
return LoginRequiredJS(w, r, user)
return LoginRequiredJS(w, r, u)
}
// ? - Where is this used? Should we use it more?
// LoginRequired is an error shown to the end-user when they try to access an area which requires them to login
func LoginRequired(w http.ResponseWriter, r *http.Request, user *User) RouteError {
return CustomError(phrases.GetErrorPhrase("login_required_body"), 401, phrases.GetErrorPhrase("no_permissions_title"), w, r, nil, user)
func LoginRequired(w http.ResponseWriter, r *http.Request, u *User) RouteError {
return CustomError(p.GetErrorPhrase("login_required_body"), 401, p.GetErrorPhrase("no_permissions_title"), w, r, nil, u)
}
// nolint
func LoginRequiredJS(w http.ResponseWriter, r *http.Request, user *User) RouteError {
func LoginRequiredJS(w http.ResponseWriter, r *http.Request, u *User) RouteError {
w.WriteHeader(401)
writeJsonError(phrases.GetErrorPhrase("login_required_body"), w)
writeJsonError(p.GetErrorPhrase("login_required_body"), w)
return HandledRouteError()
}
// SecurityError is used whenever a session mismatch is found
// ? - Should we add JS and JSQ versions of this?
func SecurityError(w http.ResponseWriter, r *http.Request, user *User) RouteError {
pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("security_error_title")), phrases.GetErrorPhrase("security_error_body")}
func SecurityError(w http.ResponseWriter, r *http.Request, u *User) RouteError {
pi := ErrorPage{errorHeader(w, u, p.GetErrorPhrase("security_error_title")), p.GetErrorPhrase("security_error_body")}
w.Header().Set("Content-Type", "text/html;charset=utf-8")
w.WriteHeader(403)
err := RenderTemplateAlias("error", "security_error", w, r, pi.Header, pi)
if err != nil {
LogError(err)
e := RenderTemplateAlias("error", "security_error", w, r, pi.Header, pi)
if e != nil {
LogError(e)
}
return HandledRouteError()
}
var microNotFoundBytes = []byte("file not found")
func MicroNotFound(w http.ResponseWriter, r *http.Request) RouteError {
w.Header().Set("Content-Type", "text/html;charset=utf-8")
w.WriteHeader(404)
_, _ = w.Write([]byte("file not found"))
_, _ = w.Write(microNotFoundBytes)
return HandledRouteError()
}
@ -337,13 +345,13 @@ func MicroNotFound(w http.ResponseWriter, r *http.Request) RouteError {
// ? - Add a JSQ version of this?
// ? - Add a user parameter?
func NotFound(w http.ResponseWriter, r *http.Request, h *Header) RouteError {
return CustomError(phrases.GetErrorPhrase("not_found_body"), 404, phrases.GetErrorPhrase("not_found_title"), w, r, h, &GuestUser)
return CustomError(p.GetErrorPhrase("not_found_body"), 404, p.GetErrorPhrase("not_found_title"), w, r, h, &GuestUser)
}
// ? - Add a user parameter?
func NotFoundJS(w http.ResponseWriter, r *http.Request) RouteError {
w.WriteHeader(404)
writeJsonError(phrases.GetErrorPhrase("not_found_body"), w)
writeJsonError(p.GetErrorPhrase("not_found_body"), w)
return HandledRouteError()
}
@ -373,11 +381,11 @@ func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWri
}
// CustomErrorJSQ is a version of CustomError which lets us handle both JSON and regular pages depending on how it's being accessed
func CustomErrorJSQ(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, h *Header, user *User, js bool) RouteError {
func CustomErrorJSQ(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, h *Header, u *User, js bool) RouteError {
if !js {
return CustomError(errmsg, errcode, errtitle, w, r, h, user)
return CustomError(errmsg, errcode, errtitle, w, r, h, u)
}
return CustomErrorJS(errmsg, errcode, w, r, user)
return CustomErrorJS(errmsg, errcode, w, r, u)
}
// CustomErrorJS is the pure JSON version of CustomError

View File

@ -12,15 +12,15 @@ import (
)
func Forums(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "forums", "forums")
bp, ferr := buildBasePage(w, r, u, "forums", "forums")
if ferr != nil {
return ferr
}
if !u.Perms.ManageForums {
return c.NoPermissions(w, r, u)
}
basePage.Header.AddScript("Sortable-1.4.0/Sortable.min.js")
basePage.Header.AddScriptAsync("panel_forums.js")
bp.Header.AddScript("Sortable-1.4.0/Sortable.min.js")
bp.Header.AddScriptAsync("panel_forums.js")
// TODO: Paginate this?
var forumList []interface{}
@ -41,15 +41,15 @@ func Forums(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
}
if r.FormValue("created") == "1" {
basePage.AddNotice("panel_forum_created")
bp.AddNotice("panel_forum_created")
} else if r.FormValue("deleted") == "1" {
basePage.AddNotice("panel_forum_deleted")
bp.AddNotice("panel_forum_deleted")
} else if r.FormValue("updated") == "1" {
basePage.AddNotice("panel_forum_updated")
bp.AddNotice("panel_forum_updated")
}
pi := c.PanelPage{basePage, forumList, nil}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_forums", &pi})
pi := c.PanelPage{bp, forumList, nil}
return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_forums", &pi})
}
func ForumsCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
@ -338,7 +338,7 @@ func forumPermsExtractDash(paramList string) (fid, gid int, e error) {
}
func ForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, u *c.User, paramList string) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "edit_forum", "forums")
bp, ferr := buildBasePage(w, r, u, "edit_forum", "forums")
if ferr != nil {
return ferr
}
@ -388,11 +388,11 @@ func ForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, u *c.User, p
addToggle("MoveTopic", fp.MoveTopic)
if r.FormValue("updated") == "1" {
basePage.AddNotice("panel_forum_perms_updated")
bp.AddNotice("panel_forum_perms_updated")
}
pi := c.PanelEditForumGroupPage{basePage, f.ID, gid, f.Name, f.Desc, f.Active, f.Preset, formattedPermList}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_forum_edit_perms", &pi})
pi := c.PanelEditForumGroupPage{bp, f.ID, gid, f.Name, f.Desc, f.Active, f.Preset, formattedPermList}
return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_forum_edit_perms", &pi})
}
func ForumsEditPermsAdvanceSubmit(w http.ResponseWriter, r *http.Request, u *c.User, paramList string) c.RouteError {

View File

@ -13,7 +13,7 @@ import (
// TODO: Link the usernames for successful registrations to the profiles
func LogsRegs(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "registration_logs", "logs")
bp, ferr := buildBasePage(w, r, u, "registration_logs", "logs")
if ferr != nil {
return ferr
}
@ -32,20 +32,20 @@ func LogsRegs(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
}
pageList := c.Paginate(page, lastPage, 5)
pi := c.PanelRegLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_reglogs", pi})
pi := c.PanelRegLogsPage{bp, llist, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_reglogs", pi})
}
// TODO: Log errors when something really screwy is going on?
// TODO: Base the slugs on the localised usernames?
func handleUnknownUser(u *c.User, err error) *c.User {
if err != nil {
func handleUnknownUser(u *c.User, e error) *c.User {
if e != nil {
return &c.User{Name: p.GetTmplPhrase("user_unknown"), Link: c.BuildProfileURL("unknown", 0)}
}
return u
}
func handleUnknownTopic(t *c.Topic, err error) *c.Topic {
if err != nil {
func handleUnknownTopic(t *c.Topic, e error) *c.Topic {
if e != nil {
return &c.Topic{Title: p.GetTmplPhrase("topic_unknown"), Link: c.BuildTopicURL("unknown", 0)}
}
return t
@ -169,7 +169,7 @@ func adminlogsElementType(action, elementType string, elementID int, actor *c.Us
}
func LogsMod(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "mod_logs", "logs")
bp, ferr := buildBasePage(w, r, u, "mod_logs", "logs")
if ferr != nil {
return ferr
}
@ -189,12 +189,12 @@ func LogsMod(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
}
pageList := c.Paginate(page, lastPage, 5)
pi := c.PanelLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_modlogs", pi})
pi := c.PanelLogsPage{bp, llist, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_modlogs", pi})
}
func LogsAdmin(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "admin_logs", "logs")
bp, ferr := buildBasePage(w, r, u, "admin_logs", "logs")
if ferr != nil {
return ferr
}
@ -214,6 +214,6 @@ func LogsAdmin(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
}
pageList := c.Paginate(page, lastPage, 5)
pi := c.PanelLogsPage{basePage, llist, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_adminlogs", pi})
pi := c.PanelLogsPage{bp, llist, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_adminlogs", pi})
}

View File

@ -9,14 +9,14 @@ import (
)
func Pages(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "pages", "pages")
bp, ferr := buildBasePage(w, r, u, "pages", "pages")
if ferr != nil {
return ferr
}
if r.FormValue("created") == "1" {
basePage.AddNotice("panel_page_created")
bp.AddNotice("panel_page_created")
} else if r.FormValue("deleted") == "1" {
basePage.AddNotice("panel_page_deleted")
bp.AddNotice("panel_page_deleted")
}
// TODO: Test the pagination here
@ -31,8 +31,8 @@ func Pages(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
}
pageList := c.Paginate(page, lastPage, 5)
pi := c.PanelCustomPagesPage{basePage, cPages, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_list", "", "panel_pages", &pi})
pi := c.PanelCustomPagesPage{bp, cPages, c.Paginator{pageList, page, lastPage}}
return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "panel_page_list", "", "panel_pages", &pi})
}
func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
@ -72,12 +72,12 @@ func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.Rout
}
func PagesEdit(w http.ResponseWriter, r *http.Request, u *c.User, spid string) c.RouteError {
basePage, ferr := buildBasePage(w, r, u, "pages_edit", "pages")
bp, ferr := buildBasePage(w, r, u, "pages_edit", "pages")
if ferr != nil {
return ferr
}
if r.FormValue("updated") == "1" {
basePage.AddNotice("panel_page_updated")
bp.AddNotice("panel_page_updated")
}
pid, err := strconv.Atoi(spid)
@ -86,13 +86,13 @@ func PagesEdit(w http.ResponseWriter, r *http.Request, u *c.User, spid string) c
}
page, err := c.Pages.Get(pid)
if err == sql.ErrNoRows {
return c.NotFound(w, r, basePage.Header)
return c.NotFound(w, r, bp.Header)
} else if err != nil {
return c.InternalError(err, w, r)
}
pi := c.PanelCustomPageEditPage{basePage, page}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_edit", "", "panel_pages_edit", &pi})
pi := c.PanelCustomPageEditPage{bp, page}
return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "panel_page_edit", "", "panel_pages_edit", &pi})
}
func PagesEditSubmit(w http.ResponseWriter, r *http.Request, u *c.User, spid string) c.RouteError {