Compare commits

..

No commits in common. "a8705c5df37a7599181a8da2dbcb46914c106a09" and "177556399dde3ceee90a33abf82c3ad3ca475997" have entirely different histories.

5 changed files with 102 additions and 120 deletions

View file

@ -29,9 +29,6 @@ func main() {
} }
// and finally, start the server // and finally, start the server
app.Logger.Printf("Starting HTTP Server on port %d", app.ListenPort) app.Logger.Printf("Listening on port %d", app.ListenPort)
err := srv.ListenAndServe() srv.ListenAndServe()
if err != nil {
app.Logger.Fatal("Failed to start HTTP Server!", "err", err)
}
} }

View file

@ -13,9 +13,9 @@ var Middleware []func(next http.Handler) http.Handler = []func(next http.Handler
middleware.RealIP, middleware.RealIP,
// plus custom request logger // plus custom request logger
func(next http.Handler) http.Handler { func(next http.Handler) http.Handler {
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
app.Logger.Info("REQUEST", "url", request.URL, "ip", request.RemoteAddr, "useragent", request.UserAgent()) app.Logger.Info("REQUEST", "url", r.URL, "ip", r.RemoteAddr, "useragent", r.UserAgent())
next.ServeHTTP(writer, request) next.ServeHTTP(w, r)
}) })
}, },
middleware.Recoverer, middleware.Recoverer,

View file

@ -29,9 +29,8 @@ func routes(app *config.AppConfig) http.Handler {
mux.Get(handler.Handles, handler.Handler) mux.Get(handler.Handles, handler.Handler)
} }
// Setup extra handlers // Setup home handler
mux.Get("/", handlers.HomeHandler) mux.Get("/", handlers.HomeHandler)
mux.Get("/robots.txt", handlers.RobotHandler)
return mux return mux
} }

View file

@ -16,7 +16,7 @@ import (
// Handler holds data required for handlers. // Handler holds data required for handlers.
type Handler struct { type Handler struct {
Handles string Handles string
Handler func(writer http.ResponseWriter, request *http.Request) Handler func(w http.ResponseWriter, r *http.Request)
} }
var app *config.AppConfig var app *config.AppConfig
@ -27,14 +27,14 @@ var Handlers = []Handler{
Handles: "/about", Handles: "/about",
Handler: makeBasicHandler("about"), Handler: makeBasicHandler("about"),
}, },
{
Handles: "/apps",
Handler: makeLinksHandler("apps"),
},
{ {
Handles: "/projects", Handles: "/projects",
Handler: makeLinksHandler("projects"), Handler: makeLinksHandler("projects"),
}, },
{
Handles: "/apps",
Handler: makeLinksHandler("apps"),
},
} }
// Initialise the handlers package. // Initialise the handlers package.
@ -43,7 +43,7 @@ func Initialise(a *config.AppConfig) {
} }
// HomeHandler handles /, generating data from Handlers // HomeHandler handles /, generating data from Handlers
func HomeHandler(writer http.ResponseWriter, request *http.Request) { func HomeHandler(w http.ResponseWriter, r *http.Request) {
page := "home.page.tmpl" page := "home.page.tmpl"
d := models.TemplateData{} d := models.TemplateData{}
@ -72,33 +72,20 @@ func HomeHandler(writer http.ResponseWriter, request *http.Request) {
d.LinkMap = make(map[string][]models.Link) d.LinkMap = make(map[string][]models.Link)
d.LinkMap["Pages"] = pages d.LinkMap["Pages"] = pages
app.Logger.Debug("handling home with some data", "data", &d) app.Logger.Debug("handling home with some data", "data", &d)
render.RenderTemplateWithData(writer, "home.page.tmpl", &d) render.RenderTemplateWithData(w, "home.page.tmpl", &d)
}
// RobotHandler creates a handler for robots.txt out of existing Handlers
func RobotHandler(writer http.ResponseWriter, request *http.Request) {
robots := fmt.Sprintf("User-agent: %s\nAllow: /\n", request.UserAgent())
for _, handler := range Handlers {
robots += fmt.Sprintf("Allow: %s\n", handler.Handles)
}
robots += "Disallow: /*\n"
fmt.Fprint(writer, robots)
} }
// makeBasicHandler returns a simple handler that renders a template from `name`.page.tmpl // makeBasicHandler returns a simple handler that renders a template from `name`.page.tmpl
func makeBasicHandler(name string) func(writer http.ResponseWriter, request *http.Request) { func makeBasicHandler(name string) func(w http.ResponseWriter, r *http.Request) {
return func(writer http.ResponseWriter, request *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
pageName := name + ".page.tmpl" pageName := name + ".page.tmpl"
render.RenderTemplate(writer, pageName) render.RenderTemplate(w, pageName)
} }
} }
// makeLinksHandler returns a handler for links.tmpl with template data from `name` // makeLinksHandler returns a handler for links.tmpl with template data from `name`
func makeLinksHandler(name string) func(writer http.ResponseWriter, request *http.Request) { func makeLinksHandler(name string) func(w http.ResponseWriter, r *http.Request) {
return func(writer http.ResponseWriter, request *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
page := "links.tmpl" page := "links.tmpl"
template, err := render.GetTemplateFromCache(page) template, err := render.GetTemplateFromCache(page)
if err != nil { if err != nil {
@ -113,6 +100,6 @@ func makeLinksHandler(name string) func(writer http.ResponseWriter, request *htt
} }
app.Logger.Debug("handling a links page", "data", &data) app.Logger.Debug("handling a links page", "data", &data)
render.RenderTemplateWithData(writer, page, &data) render.RenderTemplateWithData(w, page, &data)
} }
} }

View file

@ -26,96 +26,15 @@ func Initialise(a *config.AppConfig) {
app = a app = a
if app.UseCache { if app.UseCache {
var err error var err error
app.TemplateCache, err = generateNewTemplateCache() app.TemplateCache, err = GenerateNewTemplateCache()
if err != nil { if err != nil {
app.Logger.Fatal("Error generating template cache, bailing out!") app.Logger.Fatal("Error generating template cache, bailing out!")
} }
} }
} }
// RenderTemplate renders requested template (t), pulling from cache. // GenerateNewTemplateCache generates a new template cache.
func RenderTemplate(w http.ResponseWriter, filename string) { func GenerateNewTemplateCache() (models.TemplateCache, error) {
// TODO: implement this better
if !app.UseCache {
regenerateTemplateCache()
}
template, err := GetTemplateFromCache(filename)
if err != nil {
app.Logger.Fatalf("Tried loading %s from the cache, but %s!", filename, err)
}
data, err := GetOrGenerateTemplateData(filename)
if err != nil {
app.Logger.Error(err)
}
app.Logger.Debug(fmt.Sprintf("Executing template %s", filename), "data", &data)
err = template.Execute(data, w)
if err != nil {
app.Logger.Fatalf("Failed to execute template %s: %s", filename, err)
}
}
func RenderTemplateWithData(w http.ResponseWriter, filename string, data *models.TemplateData) {
if !app.UseCache {
regenerateTemplateCache()
}
template, err := GetTemplateFromCache(filename)
if err != nil {
app.Logger.Fatalf("Tried loading %s from the cache, but %s!", filename, err)
}
app.Logger.Debug(fmt.Sprintf("Executing template %s", filename), "data", &data)
err = template.Execute(data, w)
if err != nil {
app.Logger.Fatalf("Failed to execute template %s: %s", filename, err)
}
}
// GetTemplateFromCache gets templates from cache
func GetTemplateFromCache(filename string) (*models.TemplateCacheItem, error) {
if template, ok := app.TemplateCache.Cache[filename]; ok {
return &template, nil
} else {
return &models.TemplateCacheItem{}, errors.New("Couldn't load template from cache")
}
}
// GetOrGenerateTemplateData gets template data from file, or generate simple
func GetOrGenerateTemplateData(filename string) (*models.TemplateData, error) {
template, err := GetTemplateFromCache(filename)
if err != nil {
return &models.TemplateData{}, err
}
data, err := td.LoadTemplateData(filename)
if err == nil {
app.Logger.Debug(fmt.Sprintf("Loaded data for template %s.", filename), "data", &data)
if _, ok := data.StringMap["GeneratedAt"]; !ok {
data.StringMap["GeneratedAt"] = template.GeneratedAt.Format(time.UnixDate)
}
} else {
app.Logger.Info(fmt.Sprintf("Loading template data for %s failed, using default template data.", filename), "err", err)
data = td.MakeBasicTemplateData(template.GeneratedAt)
}
return &data, nil
}
// regenerateTemplateCache regenerates the template cache
func regenerateTemplateCache() {
c, err := generateNewTemplateCache()
if err != nil {
app.Logger.Fatal("Error generating template cache, bailing out!")
}
app.TemplateCache = c
}
// generateNewTemplateCache generates a new template cache.
func generateNewTemplateCache() (models.TemplateCache, error) {
// start with an empty map // start with an empty map
cache := models.TemplateCache{} cache := models.TemplateCache{}
cache.Cache = map[string]models.TemplateCacheItem{} cache.Cache = map[string]models.TemplateCacheItem{}
@ -161,3 +80,83 @@ func generateNewTemplateCache() (models.TemplateCache, error) {
// All was good, so return the cache, and no error // All was good, so return the cache, and no error
return cache, nil return cache, nil
} }
// RenderTemplate renders requested template (t), pulling from cache.
func RenderTemplate(w http.ResponseWriter, filename string) {
// TODO: implement this better
if !app.UseCache {
RegenerateTemplateCache()
}
template, err := GetTemplateFromCache(filename)
if err != nil {
app.Logger.Fatalf("Tried loading %s from the cache, but %s!", filename, err)
}
data, err := GetOrGenerateTemplateData(filename)
if err != nil {
app.Logger.Error(err)
}
app.Logger.Debug(fmt.Sprintf("Executing template %s", filename), "data", &data)
err = template.Execute(data, w)
if err != nil {
app.Logger.Fatalf("Failed to execute template %s: %s", filename, err)
}
}
func RenderTemplateWithData(w http.ResponseWriter, filename string, data *models.TemplateData) {
if !app.UseCache {
RegenerateTemplateCache()
}
template, err := GetTemplateFromCache(filename)
if err != nil {
app.Logger.Fatalf("Tried loading %s from the cache, but %s!", filename, err)
}
app.Logger.Debug(fmt.Sprintf("Executing template %s", filename), "data", &data)
err = template.Execute(data, w)
if err != nil {
app.Logger.Fatalf("Failed to execute template %s: %s", filename, err)
}
}
func RegenerateTemplateCache() {
c, err := GenerateNewTemplateCache()
if err != nil {
app.Logger.Fatal("Error generating template cache, bailing out!")
}
app.TemplateCache = c
}
// GetTemplateFromCache gets templates from cache
func GetTemplateFromCache(filename string) (*models.TemplateCacheItem, error) {
if template, ok := app.TemplateCache.Cache[filename]; ok {
return &template, nil
} else {
return &models.TemplateCacheItem{}, errors.New("Couldn't load template from cache")
}
}
// GetOrGenerateTemplateData gets template data from file, or generate simple
func GetOrGenerateTemplateData(filename string) (*models.TemplateData, error) {
template, err := GetTemplateFromCache(filename)
if err != nil {
return &models.TemplateData{}, err
}
data, err := td.LoadTemplateData(filename)
if err == nil {
app.Logger.Debug(fmt.Sprintf("Loaded data for template %s.", filename), "data", &data)
if _, ok := data.StringMap["GeneratedAt"]; !ok {
data.StringMap["GeneratedAt"] = template.GeneratedAt.Format(time.UnixDate)
}
} else {
app.Logger.Info(fmt.Sprintf("Loading template data for %s failed, using default template data.", filename), "err", err)
data = td.MakeBasicTemplateData(template.GeneratedAt)
}
return &data, nil
}