10f4c59cb5
Added the Go and Database versions to the Control Panel Debug Page. Renamed common.TopicsPage to common.TopicListPage. Renamed *HeaderVars to *Header. Added the Paginator struct and refactored the code to use it. io.Writers are now used instead of http.ResponseWriters in transpiled templates for greater flexibility. Added the alert, menu_alerts, and menu_item templates. Added support for more integer types in the arithmetic functions for the transpiled templates. Exported AccSelectBuilder. Added an Each method to AccSelectBuilder. Added column quoting to the order by portions of queries for the MySQL Adapter. Began work on the client side rendering of alerts. Began work on the Menu Manager and associated functionality.
89 lines
2.5 KiB
Go
89 lines
2.5 KiB
Go
package routes
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"../common"
|
|
)
|
|
|
|
var cacheControlMaxAge = "max-age=" + strconv.Itoa(common.Day) // TODO: Make this a common.Config value
|
|
|
|
// GET functions
|
|
func StaticFile(w http.ResponseWriter, r *http.Request) {
|
|
file, ok := common.StaticFiles.Get(r.URL.Path)
|
|
if !ok {
|
|
common.DebugLogf("Failed to find '%s'", r.URL.Path)
|
|
w.WriteHeader(http.StatusNotFound)
|
|
return
|
|
}
|
|
h := w.Header()
|
|
|
|
// Surely, there's a more efficient way of doing this?
|
|
t, err := time.Parse(http.TimeFormat, h.Get("If-Modified-Since"))
|
|
if err == nil && file.Info.ModTime().Before(t.Add(1*time.Second)) {
|
|
w.WriteHeader(http.StatusNotModified)
|
|
return
|
|
}
|
|
h.Set("Last-Modified", file.FormattedModTime)
|
|
h.Set("Content-Type", file.Mimetype)
|
|
h.Set("Cache-Control", cacheControlMaxAge) //Cache-Control: max-age=31536000
|
|
h.Set("Vary", "Accept-Encoding")
|
|
if strings.Contains(h.Get("Accept-Encoding"), "gzip") {
|
|
h.Set("Content-Encoding", "gzip")
|
|
h.Set("Content-Length", strconv.FormatInt(file.GzipLength, 10))
|
|
io.Copy(w, bytes.NewReader(file.GzipData)) // Use w.Write instead?
|
|
} else {
|
|
h.Set("Content-Length", strconv.FormatInt(file.Length, 10)) // Avoid doing a type conversion every time?
|
|
io.Copy(w, bytes.NewReader(file.Data))
|
|
}
|
|
// Other options instead of io.Copy: io.CopyN(), w.Write(), http.ServeContent()
|
|
}
|
|
|
|
func Overview(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
|
|
header, ferr := common.UserCheck(w, r, &user)
|
|
if ferr != nil {
|
|
return ferr
|
|
}
|
|
header.Zone = "overview"
|
|
|
|
pi := common.Page{common.GetTitlePhrase("overview"), user, header, tList, nil}
|
|
if common.RunPreRenderHook("pre_render_overview", w, r, &user, &pi) {
|
|
return nil
|
|
}
|
|
err := common.Templates.ExecuteTemplate(w, "overview.html", pi)
|
|
if err != nil {
|
|
return common.InternalError(err, w, r)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func CustomPage(w http.ResponseWriter, r *http.Request, user common.User, name string) common.RouteError {
|
|
header, ferr := common.UserCheck(w, r, &user)
|
|
if ferr != nil {
|
|
return ferr
|
|
}
|
|
header.Zone = "custom_page"
|
|
|
|
// ! Is this safe?
|
|
if common.Templates.Lookup("page_"+name+".html") == nil {
|
|
return common.NotFound(w, r, header)
|
|
}
|
|
|
|
pi := common.Page{common.GetTitlePhrase("page"), user, header, tList, nil}
|
|
// TODO: Pass the page name to the pre-render hook?
|
|
if common.RunPreRenderHook("pre_render_custom_page", w, r, &user, &pi) {
|
|
return nil
|
|
}
|
|
|
|
err := common.Templates.ExecuteTemplate(w, "page_"+name+".html", pi)
|
|
if err != nil {
|
|
return common.InternalError(err, w, r)
|
|
}
|
|
return nil
|
|
}
|