cmc-sales/go/internal/cmc/templates/templates.go

161 lines
3.8 KiB
Go

package templates
import (
"fmt"
"html/template"
"io"
"os"
"path/filepath"
"time"
)
type TemplateManager struct {
templates map[string]*template.Template
}
func NewTemplateManager(templatesDir string) (*TemplateManager, error) {
tm := &TemplateManager{
templates: make(map[string]*template.Template),
}
// Define template functions
funcMap := template.FuncMap{
"formatDate": formatDate,
"truncate": truncate,
"currency": formatCurrency,
"currentYear": func() int { return time.Now().Year() },
}
// Load all templates
layouts, err := filepath.Glob(filepath.Join(templatesDir, "layouts/*.html"))
if err != nil {
return nil, err
}
partials, err := filepath.Glob(filepath.Join(templatesDir, "partials/*.html"))
if err != nil {
return nil, err
}
// Load page templates
pages := []string{
"index.html",
"customers/index.html",
"customers/show.html",
"customers/form.html",
"customers/table.html",
"products/index.html",
"products/show.html",
"products/form.html",
"products/table.html",
"purchase-orders/index.html",
"purchase-orders/show.html",
"purchase-orders/form.html",
"purchase-orders/table.html",
"enquiries/index.html",
"enquiries/show.html",
"enquiries/form.html",
"enquiries/table.html",
"emails/index.html",
"emails/show.html",
"emails/table.html",
"emails/attachments.html",
"documents/index.html",
"documents/show.html",
"documents/table.html",
"documents/view.html",
"documents/quote-view.html",
"documents/invoice-view.html",
"documents/purchase-order-view.html",
"documents/orderack-view.html",
"documents/packinglist-view.html",
"quotes/index.html",
}
for _, page := range pages {
pagePath := filepath.Join(templatesDir, page)
files := append(layouts, partials...)
files = append(files, pagePath)
// For index pages, also include the corresponding table template
if filepath.Base(page) == "index.html" {
dir := filepath.Dir(page)
tablePath := filepath.Join(templatesDir, dir, "table.html")
// Check if table file exists before adding it
if _, err := os.Stat(tablePath); err == nil {
files = append(files, tablePath)
}
}
// For documents view page, include all document type elements
if page == "documents/view.html" {
docElements := []string{
"documents/quote-view.html",
"documents/invoice-view.html",
"documents/purchase-order-view.html",
"documents/orderack-view.html",
"documents/packinglist-view.html",
}
for _, elem := range docElements {
elemPath := filepath.Join(templatesDir, elem)
if _, err := os.Stat(elemPath); err == nil {
files = append(files, elemPath)
}
}
}
tmpl, err := template.New(filepath.Base(page)).Funcs(funcMap).ParseFiles(files...)
if err != nil {
return nil, err
}
tm.templates[page] = tmpl
}
return tm, nil
}
func (tm *TemplateManager) Render(w io.Writer, name string, data interface{}) error {
tmpl, ok := tm.templates[name]
if !ok {
return template.New("error").Execute(w, "Template not found")
}
return tmpl.ExecuteTemplate(w, "base", data)
}
func (tm *TemplateManager) RenderPartial(w io.Writer, templateFile, templateName string, data interface{}) error {
tmpl, ok := tm.templates[templateFile]
if !ok {
return template.New("error").Execute(w, "Template not found")
}
return tmpl.ExecuteTemplate(w, templateName, data)
}
// Template helper functions
func formatDate(t interface{}) string {
switch v := t.(type) {
case time.Time:
return v.Format("2006-01-02")
case string:
if tm, err := time.Parse("2006-01-02 15:04:05", v); err == nil {
return tm.Format("2006-01-02")
}
return v
default:
return fmt.Sprintf("%v", v)
}
}
func truncate(s string, n int) string {
if len(s) <= n {
return s
}
return s[:n] + "..."
}
func formatCurrency(amount float64) string {
return fmt.Sprintf("$%.2f", amount)
}