package mailer import ( "bytes" htmltemplate "html/template" "os" "path/filepath" texttemplate "text/template" ) const defaultEmailTemplateDir = "web/emails/templates" type TemplateData struct { AppName string BaseURL string VerifyURL string ResetURL string UserEmail string } type TemplateRenderer struct { templatesDir string } func NewTemplateRenderer(templatesDir string) *TemplateRenderer { if templatesDir == "" { templatesDir = defaultEmailTemplateDir } return &TemplateRenderer{templatesDir: templatesDir} } func (r *TemplateRenderer) RenderVerifyEmail(data TemplateData) (htmlBody string, textBody string, err error) { return r.render("verify_email", data) } func (r *TemplateRenderer) RenderResetPassword(data TemplateData) (htmlBody string, textBody string, err error) { return r.render("reset_password", data) } func (r *TemplateRenderer) render(baseName string, data TemplateData) (string, string, error) { htmlPath := filepath.Join(r.templatesDir, baseName+".html") textPath := filepath.Join(r.templatesDir, baseName+".txt") htmlBody, err := renderHTMLFile(htmlPath, data) if err != nil { return "", "", err } textBody, err := renderTextFile(textPath, data) if err != nil { return "", "", err } return htmlBody, textBody, nil } func renderHTMLFile(path string, data TemplateData) (string, error) { content, err := os.ReadFile(path) if err != nil { return "", err } tmpl, err := htmltemplate.New(filepath.Base(path)).Parse(string(content)) if err != nil { return "", err } var buf bytes.Buffer if err := tmpl.Execute(&buf, data); err != nil { return "", err } return buf.String(), nil } func renderTextFile(path string, data TemplateData) (string, error) { content, err := os.ReadFile(path) if err != nil { return "", err } tmpl, err := texttemplate.New(filepath.Base(path)).Parse(string(content)) if err != nil { return "", err } var buf bytes.Buffer if err := tmpl.Execute(&buf, data); err != nil { return "", err } return buf.String(), nil }