123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- package templates
- import (
- "embed"
- "encoding/json"
- "path/filepath"
- "strings"
- "text/template"
- )
- //go:embed *.tmpl
- var templateFS embed.FS
- // TemplateEngine provides template rendering functionality for Dockerfiles
- type TemplateEngine struct {
- templates map[string]*template.Template
- }
- // NewTemplateEngine creates a new template engine with all built-in templates
- func NewTemplateEngine() (*TemplateEngine, error) {
- te := &TemplateEngine{
- templates: make(map[string]*template.Template),
- }
- // Create template functions
- funcMap := template.FuncMap{
- "join": func(sep string, items []string) string {
- return strings.Join(items, sep)
- },
- "toJSON": func(v interface{}) string {
- b, _ := json.Marshal(v)
- return string(b)
- },
- "hasPrefix": func(prefix, str string) bool {
- return strings.HasPrefix(str, prefix)
- },
- "hasSuffix": func(suffix, str string) bool {
- return strings.HasSuffix(str, suffix)
- },
- "contains": func(substr, str string) bool {
- return strings.Contains(str, substr)
- },
- "lower": strings.ToLower,
- "upper": strings.ToUpper,
- "trim": strings.TrimSpace,
- }
- // Load all template files
- entries, err := templateFS.ReadDir(".")
- if err != nil {
- return nil, err
- }
- for _, entry := range entries {
- if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".tmpl") {
- name := strings.TrimSuffix(entry.Name(), ".tmpl")
- content, err := templateFS.ReadFile(entry.Name())
- if err != nil {
- return nil, err
- }
- tmpl, err := template.New(name).Funcs(funcMap).Parse(string(content))
- if err != nil {
- return nil, err
- }
- te.templates[name] = tmpl
- }
- }
- return te, nil
- }
- // Render renders a template with the given data
- func (te *TemplateEngine) Render(templateName string, data interface{}) (string, error) {
- tmpl, exists := te.templates[templateName]
- if !exists {
- return "", &template.ExecError{
- Name: "template not found: " + templateName,
- }
- }
- var buf strings.Builder
- err := tmpl.Execute(&buf, data)
- if err != nil {
- return "", err
- }
- return buf.String(), nil
- }
- // GetTemplateNames returns all available template names
- func (te *TemplateEngine) GetTemplateNames() []string {
- names := make([]string, 0, len(te.templates))
- for name := range te.templates {
- names = append(names, name)
- }
- return names
- }
- // RenderFromFile renders a template from an external file (for custom templates)
- func (te *TemplateEngine) RenderFromFile(templatePath string, data interface{}) (string, error) {
- funcMap := template.FuncMap{
- "join": func(sep string, items []string) string {
- return strings.Join(items, sep)
- },
- "toJSON": func(v interface{}) string {
- b, _ := json.Marshal(v)
- return string(b)
- },
- "hasPrefix": func(prefix, str string) bool {
- return strings.HasPrefix(str, prefix)
- },
- "hasSuffix": func(suffix, str string) bool {
- return strings.HasSuffix(str, suffix)
- },
- "contains": func(substr, str string) bool {
- return strings.Contains(str, substr)
- },
- "lower": strings.ToLower,
- "upper": strings.ToUpper,
- "trim": strings.TrimSpace,
- }
- name := filepath.Base(templatePath)
- tmpl, err := template.New(name).Funcs(funcMap).ParseFiles(templatePath)
- if err != nil {
- return "", err
- }
- var buf strings.Builder
- err = tmpl.Execute(&buf, data)
- if err != nil {
- return "", err
- }
- return buf.String(), nil
- }
|