Want to contribute? Fork me on Codeberg.org!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

87 lines
2.1 KiB

package httputils
import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"text/template"
"time"
)
type TemplateSet struct {
templates *template.Template
paths []string
modTimes map[string]time.Time
}
func newTemplateSet(partials *TemplateSet, paths ...string) TemplateSet {
var partialPaths []string
if partials == nil {
partialPaths = make([]string, 0)
} else {
partialPaths = partials.paths
}
allPaths := append(partialPaths, paths...)
modTimes := make(map[string]time.Time)
for _, path := range allPaths {
fileInfo, _ := os.Stat(path)
modTimes[path] = fileInfo.ModTime()
}
templates := template.Must(template.ParseFiles(allPaths...))
return TemplateSet{
templates: templates,
paths: allPaths,
modTimes: modTimes,
}
}
func NewTemplateSet(paths ...string) TemplateSet {
for i, path := range paths {
paths[i] = fmt.Sprintf("%s/%s", templateFolder, path)
}
return newTemplateSet(&partials, paths...)
}
func (templateSet *TemplateSet) ExecuteTemplate(wr io.Writer, name string, data any) error {
templateSet.reloadTemplatesIfModified()
return templateSet.templates.ExecuteTemplate(wr, name, data)
}
func (templateSet *TemplateSet) reloadTemplateIfModified(path string) {
fileInfo, _ := os.Stat(path)
modTime := fileInfo.ModTime()
if modTime.After(templateSet.modTimes[path]) {
fmt.Printf("Reloading template %s...\n", path)
templateSet.templates.ParseFiles(path)
templateSet.modTimes[path] = modTime
}
}
func (templateSet *TemplateSet) reloadTemplatesIfModified() {
for _, path := range templateSet.paths {
templateSet.reloadTemplateIfModified(path)
}
}
func getTemplatePathsInDirectory(directory string) (paths []string, err error) {
paths = make([]string, 0)
err = filepath.Walk(directory, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && strings.HasSuffix(path, ".html") {
paths = append(paths, path)
}
return nil
})
return
}
const templateFolder = "templates"
const partialsFolder = templateFolder + "/partials"
var paths, _ = getTemplatePathsInDirectory(partialsFolder)
var partials = newTemplateSet(nil, paths...)