1package render
2
3import (
4 "bytes"
5 "fmt"
6 "html/template"
7 "io/fs"
8 "path"
9
10 "github.com/bnema/gordon/internal/server"
11)
12
13type Renderer struct {
14 Template *template.Template
15 ParseError error
16 BuildVersion string
17}
18
19// Render function renders the template with the given data
20func (r *Renderer) Render(data interface{}, a *server.App) (string, error) {
21 if r.ParseError != nil {
22 return "", fmt.Errorf("failed to parse template: %w", r.ParseError)
23
24 }
25 if r.Template == nil {
26 return "", fmt.Errorf("template is nil")
27 }
28 // Type assert data to map[string]interface{} to add BuildVersion
29 dataMap, ok := data.(map[string]interface{})
30 if !ok {
31 return "", fmt.Errorf("data is not a map[string]interface{}")
32 }
33
34 // Automatically add BuildVersion to the data map
35 dataMap["BuildVersion"] = r.BuildVersion
36 buf := new(bytes.Buffer)
37 err := r.Template.Execute(buf, dataMap)
38 if err != nil {
39 return "", fmt.Errorf("failed to execute template: %w", err)
40 }
41
42 return buf.String(), nil
43}
44
45// GetHTMLRenderer function returns a new Renderer instance
46func GetHTMLRenderer(mainPath string, filename string, fs fs.FS, a *server.App, fragmentsPath ...string) (*Renderer, error) {
47 // Full path to the main template
48 fullPath := path.Join(mainPath, filename)
49 // Check if the file exists in the provided fs.FS using fs.Open
50 file, err := fs.Open(fullPath)
51 if err != nil {
52 return nil, fmt.Errorf("failed to open %s: %w", filename, err)
53 }
54 file.Close()
55
56 // Parse the main template
57 tmpl, err := template.New(filename).ParseFS(fs, fullPath)
58 if err != nil {
59 return nil, fmt.Errorf("failed to parse %s: %w", filename, err)
60 }
61
62 // If a fragments path is provided, parse the fragment templates
63 if len(fragmentsPath) > 0 && fragmentsPath[0] != "" {
64 fragmentsGlob := path.Join(fragmentsPath[0], "*.gohtml")
65 _, err = tmpl.ParseFS(fs, fragmentsGlob)
66 if err != nil {
67 return nil, fmt.Errorf("failed to parse fragments: %w", err)
68 }
69 }
70
71 // Return the Renderer instance
72 return &Renderer{
73 Template: tmpl,
74 BuildVersion: a.Config.Build.BuildVersion,
75 }, nil
76}