From 94017dc040f545d606173126a857e5afd979c3e6 Mon Sep 17 00:00:00 2001 From: Lou Knauer Date: Wed, 6 Jul 2022 15:00:08 +0200 Subject: [PATCH] embed templates into binary (issue #2) --- cmd/cc-backend/main.go | 13 +++--- internal/routerConfig/routes.go | 8 ++-- internal/templates/templates.go | 80 --------------------------------- 3 files changed, 10 insertions(+), 91 deletions(-) delete mode 100644 internal/templates/templates.go diff --git a/cmd/cc-backend/main.go b/cmd/cc-backend/main.go index 6e357f3..2cc6926 100644 --- a/cmd/cc-backend/main.go +++ b/cmd/cc-backend/main.go @@ -31,7 +31,6 @@ import ( "github.com/ClusterCockpit/cc-backend/internal/repository" "github.com/ClusterCockpit/cc-backend/internal/routerConfig" "github.com/ClusterCockpit/cc-backend/internal/runtimeEnv" - "github.com/ClusterCockpit/cc-backend/internal/templates" "github.com/ClusterCockpit/cc-backend/pkg/log" "github.com/ClusterCockpit/cc-backend/web" "github.com/google/gops/agent" @@ -297,15 +296,15 @@ func main() { r.HandleFunc("/login", func(rw http.ResponseWriter, r *http.Request) { rw.Header().Add("Content-Type", "text/html; charset=utf-8") - templates.Render(rw, r, "login.tmpl", &templates.Page{Title: "Login"}) + web.RenderTemplate(rw, r, "login.tmpl", &web.Page{Title: "Login"}) }).Methods(http.MethodGet) r.HandleFunc("/imprint", func(rw http.ResponseWriter, r *http.Request) { rw.Header().Add("Content-Type", "text/html; charset=utf-8") - templates.Render(rw, r, "imprint.tmpl", &templates.Page{Title: "Imprint"}) + web.RenderTemplate(rw, r, "imprint.tmpl", &web.Page{Title: "Imprint"}) }) r.HandleFunc("/privacy", func(rw http.ResponseWriter, r *http.Request) { rw.Header().Add("Content-Type", "text/html; charset=utf-8") - templates.Render(rw, r, "privacy.tmpl", &templates.Page{Title: "Privacy"}) + web.RenderTemplate(rw, r, "privacy.tmpl", &web.Page{Title: "Privacy"}) }) // Some routes, such as /login or /query, should only be accessible to a user that is logged in. @@ -321,7 +320,7 @@ func main() { func(rw http.ResponseWriter, r *http.Request, err error) { rw.Header().Add("Content-Type", "text/html; charset=utf-8") rw.WriteHeader(http.StatusUnauthorized) - templates.Render(rw, r, "login.tmpl", &templates.Page{ + web.RenderTemplate(rw, r, "login.tmpl", &web.Page{ Title: "Login failed - ClusterCockpit", Error: err.Error(), }) @@ -330,7 +329,7 @@ func main() { r.Handle("/logout", authentication.Logout(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { rw.Header().Add("Content-Type", "text/html; charset=utf-8") rw.WriteHeader(http.StatusOK) - templates.Render(rw, r, "login.tmpl", &templates.Page{ + web.RenderTemplate(rw, r, "login.tmpl", &web.Page{ Title: "Bye - ClusterCockpit", Info: "Logout sucessful", }) @@ -344,7 +343,7 @@ func main() { // On failure: func(rw http.ResponseWriter, r *http.Request, err error) { rw.WriteHeader(http.StatusUnauthorized) - templates.Render(rw, r, "login.tmpl", &templates.Page{ + web.RenderTemplate(rw, r, "login.tmpl", &web.Page{ Title: "Authentication failed - ClusterCockpit", Error: err.Error(), }) diff --git a/internal/routerConfig/routes.go b/internal/routerConfig/routes.go index cb888eb..daba892 100644 --- a/internal/routerConfig/routes.go +++ b/internal/routerConfig/routes.go @@ -13,9 +13,9 @@ import ( "github.com/ClusterCockpit/cc-backend/internal/graph" "github.com/ClusterCockpit/cc-backend/internal/graph/model" "github.com/ClusterCockpit/cc-backend/internal/repository" - "github.com/ClusterCockpit/cc-backend/internal/templates" "github.com/ClusterCockpit/cc-backend/pkg/log" "github.com/ClusterCockpit/cc-backend/pkg/schema" + "github.com/ClusterCockpit/cc-backend/web" "github.com/gorilla/mux" ) @@ -271,9 +271,9 @@ func SetupRoutes(router *mux.Router) { isAdmin = user.HasRole(auth.RoleAdmin) } - page := templates.Page{ + page := web.Page{ Title: title, - User: templates.User{Username: username, IsAdmin: isAdmin}, + User: web.User{Username: username, IsAdmin: isAdmin}, Config: conf, Infos: infos, } @@ -282,7 +282,7 @@ func SetupRoutes(router *mux.Router) { page.FilterPresets = buildFilterPresets(r.URL.Query()) } - templates.Render(rw, r, route.Template, &page) + web.RenderTemplate(rw, r, route.Template, &page) }) } } diff --git a/internal/templates/templates.go b/internal/templates/templates.go deleted file mode 100644 index 31653b0..0000000 --- a/internal/templates/templates.go +++ /dev/null @@ -1,80 +0,0 @@ -package templates - -import ( - "html/template" - "net/http" - "os" - - "github.com/ClusterCockpit/cc-backend/internal/config" - "github.com/ClusterCockpit/cc-backend/pkg/log" -) - -var templatesDir string -var debugMode bool = os.Getenv("DEBUG") == "1" -var templates map[string]*template.Template = map[string]*template.Template{} - -type User struct { - Username string // Username of the currently logged in user - IsAdmin bool -} - -type Page struct { - Title string // Page title - Error string // For generic use (e.g. the exact error message on /login) - Info string // For generic use (e.g. "Logout successfull" on /login) - User User // Information about the currently logged in user - Clusters []string // List of all clusters for use in the Header - FilterPresets map[string]interface{} // For pages with the Filter component, this can be used to set initial filters. - Infos map[string]interface{} // For generic use (e.g. username for /monitoring/user/, job id for /monitoring/job/) - Config map[string]interface{} // UI settings for the currently logged in user (e.g. line width, ...) -} - -func init() { - bp := "./" - ebp := os.Getenv("BASEPATH") - - if ebp != "" { - bp = ebp - } - templatesDir = bp + "web/templates/" - base := template.Must(template.ParseFiles(templatesDir + "base.tmpl")) - files := []string{ - "home.tmpl", "404.tmpl", "login.tmpl", - "imprint.tmpl", "privacy.tmpl", - "config.tmpl", - "monitoring/jobs.tmpl", - "monitoring/job.tmpl", - "monitoring/taglist.tmpl", - "monitoring/list.tmpl", - "monitoring/user.tmpl", - "monitoring/systems.tmpl", - "monitoring/status.tmpl", - "monitoring/node.tmpl", - "monitoring/analysis.tmpl", - } - - for _, file := range files { - templates[file] = template.Must(template.Must(base.Clone()).ParseFiles(templatesDir + file)) - } -} - -func Render(rw http.ResponseWriter, r *http.Request, file string, page *Page) { - t, ok := templates[file] - if !ok { - panic("templates must be predefinied!") - } - - if debugMode { - t = template.Must(template.ParseFiles(templatesDir+"base.tmpl", templatesDir+file)) - } - - if page.Clusters == nil { - for _, c := range config.Clusters { - page.Clusters = append(page.Clusters, c.Name) - } - } - - if err := t.Execute(rw, page); err != nil { - log.Errorf("template error: %s", err.Error()) - } -}