engine.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package templates
  2. import (
  3. "embed"
  4. "encoding/json"
  5. "path/filepath"
  6. "strings"
  7. "text/template"
  8. )
  9. //go:embed *.tmpl
  10. var templateFS embed.FS
  11. // TemplateEngine provides template rendering functionality for Dockerfiles
  12. type TemplateEngine struct {
  13. templates map[string]*template.Template
  14. }
  15. // NewTemplateEngine creates a new template engine with all built-in templates
  16. func NewTemplateEngine() (*TemplateEngine, error) {
  17. te := &TemplateEngine{
  18. templates: make(map[string]*template.Template),
  19. }
  20. // Create template functions
  21. funcMap := template.FuncMap{
  22. "join": func(sep string, items []string) string {
  23. return strings.Join(items, sep)
  24. },
  25. "toJSON": func(v interface{}) string {
  26. b, _ := json.Marshal(v)
  27. return string(b)
  28. },
  29. "hasPrefix": func(prefix, str string) bool {
  30. return strings.HasPrefix(str, prefix)
  31. },
  32. "hasSuffix": func(suffix, str string) bool {
  33. return strings.HasSuffix(str, suffix)
  34. },
  35. "contains": func(substr, str string) bool {
  36. return strings.Contains(str, substr)
  37. },
  38. "lower": strings.ToLower,
  39. "upper": strings.ToUpper,
  40. "trim": strings.TrimSpace,
  41. }
  42. // Load all template files
  43. entries, err := templateFS.ReadDir(".")
  44. if err != nil {
  45. return nil, err
  46. }
  47. for _, entry := range entries {
  48. if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".tmpl") {
  49. name := strings.TrimSuffix(entry.Name(), ".tmpl")
  50. content, err := templateFS.ReadFile(entry.Name())
  51. if err != nil {
  52. return nil, err
  53. }
  54. tmpl, err := template.New(name).Funcs(funcMap).Parse(string(content))
  55. if err != nil {
  56. return nil, err
  57. }
  58. te.templates[name] = tmpl
  59. }
  60. }
  61. return te, nil
  62. }
  63. // Render renders a template with the given data
  64. func (te *TemplateEngine) Render(templateName string, data interface{}) (string, error) {
  65. tmpl, exists := te.templates[templateName]
  66. if !exists {
  67. return "", &template.ExecError{
  68. Name: "template not found: " + templateName,
  69. }
  70. }
  71. var buf strings.Builder
  72. err := tmpl.Execute(&buf, data)
  73. if err != nil {
  74. return "", err
  75. }
  76. return buf.String(), nil
  77. }
  78. // GetTemplateNames returns all available template names
  79. func (te *TemplateEngine) GetTemplateNames() []string {
  80. names := make([]string, 0, len(te.templates))
  81. for name := range te.templates {
  82. names = append(names, name)
  83. }
  84. return names
  85. }
  86. // RenderFromFile renders a template from an external file (for custom templates)
  87. func (te *TemplateEngine) RenderFromFile(templatePath string, data interface{}) (string, error) {
  88. funcMap := template.FuncMap{
  89. "join": func(sep string, items []string) string {
  90. return strings.Join(items, sep)
  91. },
  92. "toJSON": func(v interface{}) string {
  93. b, _ := json.Marshal(v)
  94. return string(b)
  95. },
  96. "hasPrefix": func(prefix, str string) bool {
  97. return strings.HasPrefix(str, prefix)
  98. },
  99. "hasSuffix": func(suffix, str string) bool {
  100. return strings.HasSuffix(str, suffix)
  101. },
  102. "contains": func(substr, str string) bool {
  103. return strings.Contains(str, substr)
  104. },
  105. "lower": strings.ToLower,
  106. "upper": strings.ToUpper,
  107. "trim": strings.TrimSpace,
  108. }
  109. name := filepath.Base(templatePath)
  110. tmpl, err := template.New(name).Funcs(funcMap).ParseFiles(templatePath)
  111. if err != nil {
  112. return "", err
  113. }
  114. var buf strings.Builder
  115. err = tmpl.Execute(&buf, data)
  116. if err != nil {
  117. return "", err
  118. }
  119. return buf.String(), nil
  120. }