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