package view import ( "errors" "html/template" "io" "log" "net/http" "os" "path" "git.aiterp.net/AiteRP/aitestory/server" "git.aiterp.net/gisle/wrouter/response" ) var wd, _ = os.Getwd() var cache = make(map[string]*template.Template) var argsCache = make(map[string][]string) // Register registers a template and compiles it for rendering. This should be done // in the beginning since an error will terminate the server func Register(name string, base string, fragments ...string) { rootPath := server.Main.Config.Directories.Templates for i, fragment := range fragments { fragments[i] = path.Join(rootPath, fragment+".tmpl") } args := append([]string{path.Join(rootPath, name+".tmpl"), path.Join(rootPath, base+".tmpl")}, fragments...) tmpl, err := template.New(name).ParseFiles(args...) if err != nil { log.Fatalf("Failed to register %s: %s", name, err) } argsCache[name] = args cache[name] = tmpl } // Render renders a template with the name it was registered with, and with the // view model. The view model is expected to be the correct model from the viewmodel // package func Render(w http.ResponseWriter, name string, status int, viewModel interface{}) { var tmpl *template.Template var err error if server.Main.Config.Server.Debug { tmpl, err = template.New(name).ParseFiles(argsCache[name]...) if err != nil { response.Text(w, 500, "Failed to run template "+name+": "+err.Error()) return } } else { var ok bool tmpl, ok = cache[name] if !ok { response.Text(w, 500, "Template not found: "+name) return } } w.WriteHeader(status) err = tmpl.ExecuteTemplate(w, "base", viewModel) if err != nil { log.Println("Template error:", err.Error()) } } // Run runs the template to a simple io.Writer. It's made for testing func Run(w io.Writer, name string, viewModel interface{}) error { tmpl, ok := cache[name] if !ok { return errors.New("template not found") } return tmpl.ExecuteTemplate(w, "base", viewModel) } func init() { Register("index", "base/default") Register("login", "base/default") }