2022-10-20 16:59:33 +00:00
|
|
|
package templating
|
|
|
|
|
|
|
|
import (
|
2024-07-10 22:45:04 +00:00
|
|
|
"GoWeb/internal"
|
2023-12-23 03:03:15 +00:00
|
|
|
"fmt"
|
2022-10-20 16:59:33 +00:00
|
|
|
"html/template"
|
2023-12-23 03:03:15 +00:00
|
|
|
"io/fs"
|
2023-09-03 20:45:12 +00:00
|
|
|
"log/slog"
|
2022-10-20 16:59:33 +00:00
|
|
|
"net/http"
|
|
|
|
)
|
|
|
|
|
2024-07-10 22:45:04 +00:00
|
|
|
var templates = make(map[string]*template.Template) // This is only used here, does not need to be in internal.Deps
|
2022-10-20 16:59:33 +00:00
|
|
|
|
2024-07-02 02:19:48 +00:00
|
|
|
func BuildPages(app *app.Deps) error {
|
2023-12-23 03:03:15 +00:00
|
|
|
basePath := app.Config.Template.BaseName
|
|
|
|
|
|
|
|
baseContent, err := app.Res.ReadFile(basePath)
|
2023-02-05 18:46:47 +00:00
|
|
|
if err != nil {
|
2023-12-23 03:03:15 +00:00
|
|
|
return fmt.Errorf("error reading base file: %w", err)
|
2023-02-05 18:46:47 +00:00
|
|
|
}
|
|
|
|
|
2023-12-23 03:03:15 +00:00
|
|
|
base, err := template.New(basePath).Parse(string(baseContent)) // Sets filepath as name and parses content
|
2023-02-05 18:46:47 +00:00
|
|
|
if err != nil {
|
2023-12-23 03:03:15 +00:00
|
|
|
return fmt.Errorf("error parsing base file: %w", err)
|
2023-02-05 18:46:47 +00:00
|
|
|
}
|
|
|
|
|
2023-12-23 03:03:15 +00:00
|
|
|
readFilesRecursively := func(fsys fs.FS, root string) ([]string, error) {
|
|
|
|
var files []string
|
|
|
|
err := fs.WalkDir(fsys, root, func(path string, d fs.DirEntry, err error) error {
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error walking the path %q: %w", path, err)
|
|
|
|
}
|
|
|
|
if !d.IsDir() {
|
|
|
|
files = append(files, path)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
return files, err
|
2023-02-05 18:46:47 +00:00
|
|
|
}
|
|
|
|
|
2023-12-23 03:03:15 +00:00
|
|
|
// Get all file paths in the directory tree
|
|
|
|
filePaths, err := readFilesRecursively(app.Res, app.Config.Template.ContentPath)
|
2023-02-05 18:46:47 +00:00
|
|
|
if err != nil {
|
2023-12-23 03:03:15 +00:00
|
|
|
return fmt.Errorf("error reading files recursively: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, contentPath := range filePaths { // Create a new template base + content for each page
|
|
|
|
content, err := app.Res.ReadFile(contentPath)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error reading content file %s: %w", contentPath, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
t, err := base.Clone()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error cloning base template: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = t.Parse(string(content))
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error parsing content: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
templates[contentPath] = t
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func RenderTemplate(w http.ResponseWriter, contentPath string, data any) {
|
|
|
|
t, ok := templates[contentPath]
|
|
|
|
if !ok {
|
|
|
|
err := fmt.Errorf("template not found for path: %s", contentPath)
|
2023-09-03 20:45:12 +00:00
|
|
|
slog.Error(err.Error())
|
2023-12-23 03:03:15 +00:00
|
|
|
http.Error(w, "Template not found", 404)
|
2023-02-05 18:46:47 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-12-23 03:03:15 +00:00
|
|
|
err := t.Execute(w, data) // Execute prebuilt template with dynamic data
|
2022-10-20 16:59:33 +00:00
|
|
|
if err != nil {
|
2023-12-23 03:03:15 +00:00
|
|
|
err = fmt.Errorf("error executing template: %w", err)
|
2023-09-03 20:45:12 +00:00
|
|
|
slog.Error(err.Error())
|
2022-10-20 16:59:33 +00:00
|
|
|
http.Error(w, err.Error(), 500)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|