package render import ( "bytes" "errors" "fmt" "go-udemy-web-1/internal/config" "go-udemy-web-1/internal/helpers" "go-udemy-web-1/internal/models" "html/template" "net/http" "path/filepath" "github.com/justinas/nosurf" ) var functions = template.FuncMap{} var ( app *config.AppConfig pathToTemplates = "./templates" ) // NewTemplates sets the config for the template package func NewTemplates(a *config.AppConfig) { app = a } // AddDefaultData adds default template data func AddDefaultData(td *models.TemplateData, r *http.Request) *models.TemplateData { td.Flash = app.Session.PopString(r.Context(), "flash") td.Warning = app.Session.PopString(r.Context(), "warning") td.Error = app.Session.PopString(r.Context(), "error") td.CSRFToken = nosurf.Token(r) return td } // RenderTemplate renders a HTML template file func RenderTemplate(w http.ResponseWriter, r *http.Request, tmpl string, td *models.TemplateData) error { var tc map[string]*template.Template if app.UseCache { // get the template cache from the app config tc = app.TemplateCahce } else { tc, _ = CreateTemplateCache() } // get requested template from cache t, ok := tc[tmpl] if !ok { return errors.New("could not get template from template cache") } // Write to a buffer to make sure that the template can be read and // written successfully buf := new(bytes.Buffer) td = AddDefaultData(td, r) err := t.Execute(buf, td) if err != nil { helpers.ServerError(w, err) return err } // render the template _, err = buf.WriteTo(w) if err != nil { helpers.ServerError(w, err) return err } return nil } func CreateTemplateCache() (map[string]*template.Template, error) { myCache := map[string]*template.Template{} // get all of the files named *.page.tmpl from templates pages, err := filepath.Glob(fmt.Sprintf("%s/*.page.tmpl", pathToTemplates)) if err != nil { return myCache, err } // range through all files ending with *page.tmpl for _, page := range pages { name := filepath.Base(page) ts, err := template.New(name).Funcs(functions).ParseFiles(page) if err != nil { return myCache, err } matches, err := filepath.Glob(fmt.Sprintf("%s/*.layout.tmpl", pathToTemplates)) if err != nil { return myCache, err } if len(matches) > 0 { ts, err = ts.ParseGlob(fmt.Sprintf("%s/*.layout.tmpl", pathToTemplates)) if err != nil { return myCache, err } } myCache[name] = ts } return myCache, nil }