package servlet import ( "errors" "fmt" util "geniuscartel.xyz/vinegar/vinegarUtil" "html/template" "io/ioutil" "net/http" "os" "path" "strings" ) type ( TemplateManager struct { templatePath string componentPath string templates map[string]*template.Template components map[string]template.HTML mixins map[string]string Templates []string } ) func NewTemplateManager(templatePath string, componentPath string) *TemplateManager { templates := make(map[string]*template.Template) components := make(map[string]template.HTML) tm := TemplateManager{templatePath: templatePath, componentPath: componentPath, templates: templates, components: components} tm.loadAssets() return &tm } func (tm *TemplateManager) loadAssets() { templateFiles, err := os.ReadDir(tm.templatePath) if err != nil { panic(err) } for _, templateFile := range templateFiles { if !templateFile.IsDir() { filePath := path.Join(tm.templatePath, templateFile.Name()) dataContent, exists := util.GetDiskContent(filePath) if !exists { panic("Could not read file contents for " + filePath) } tmpl := template.New(templateFile.Name()) tmpl.Parse(string(*dataContent)) tm.templates[templateFile.Name()] = tmpl tm.Templates = append(tm.Templates, templateFile.Name()) } } componentFiles, err := os.ReadDir(tm.componentPath) if err != nil { panic(err) } for _, componentFile := range componentFiles { if !componentFile.IsDir() { filePath := path.Join(tm.componentPath, componentFile.Name()) contentBytes, exists := util.GetDiskContent(filePath) if !exists { panic("could not find file for " + filePath) return } content := string(*contentBytes) tm.components[componentFile.Name()] = template.HTML(content) } } } func (tm *TemplateManager) RenderTemplate(key string) string { tmpl, exists := tm.templates[key] if !exists { panic("Could not load template for key: " + key) } fmt.Println() buff := strings.Builder{} err := tmpl.Execute(&buff, tm) if err != nil { panic(err) } return buff.String() } func (tm *TemplateManager) GetComponent(key string) template.HTML { content, exists := tm.components[key] if !exists { panic("Could not load data for key: " + key) return "" } return content } func (tm *TemplateManager) GetMixin(key string) template.HTML { content, exists := tm.mixins[key] if exists { return template.HTML(content) } else { return "" } } func (tm *TemplateManager) AddMixin(key string, value string) error { tm.mixins[key] = value return nil } func (tm *TemplateManager) AddMixinFromFile(key string, pathlike string) error { content, exists := util.GetDiskContent(pathlike) if exists { tm.AddMixin(key, string(*content)) return nil } else { return errors.New("mixin source file not found at " + pathlike) } } func (tm *TemplateManager) RenderAllToFile(pathlike string) { for _, v := range tm.Templates { path := path.Join(pathlike, v) tmpl := tm.templates[v] buff := strings.Builder{} err := tmpl.Execute(&buff, tm) if err != nil { panic(err) } err = ioutil.WriteFile(path, []byte(buff.String()), 0755) if err != nil { panic(err) } } } func RenderTemplate(w http.ResponseWriter, pathlike string, data any) { templateHelper := template.New(pathlike) f, err := os.OpenFile(pathlike, os.O_RDONLY, 0777) if err != nil { panic(err) } defer f.Close() content, err := ioutil.ReadAll(f) if err != nil { panic(err) } templ, err := templateHelper.Parse(string(content)) err = templ.Execute(w, data) if err != nil { panic(err) } }