···
···
38
-
t map[string]*template.Template
39
+
t map[string]*template.Template
42
+
templateDir string // Path to templates on disk for dev mode
41
-
func NewPages() *Pages {
42
-
templates := make(map[string]*template.Template)
45
+
func NewPages(dev bool) *Pages {
47
+
t: make(map[string]*template.Template),
50
+
templateDir: "appview/pages",
53
+
// Initial load of all templates
54
+
p.loadAllTemplates()
59
+
func (p *Pages) loadAllTemplates() {
60
+
templates := make(map[string]*template.Template)
var fragmentPaths []string
63
+
// Use embedded FS for initial loading
// First, collect all fragment paths
46
-
err := fs.WalkDir(Files, "templates", func(path string, d fs.DirEntry, err error) error {
65
+
err := fs.WalkDir(p.embedFS, "templates", func(path string, d fs.DirEntry, err error) error {
if !strings.HasSuffix(path, ".html") {
if !strings.Contains(path, "fragments/") {
name := strings.TrimPrefix(path, "templates/")
name = strings.TrimSuffix(name, ".html")
tmpl, err := template.New(name).
68
-
ParseFS(Files, path)
82
+
ParseFS(p.embedFS, path)
log.Fatalf("setting up fragment: %v", err)
fragmentPaths = append(fragmentPaths, path)
log.Printf("loaded fragment: %s", name)
···
// Then walk through and setup the rest of the templates
83
-
err = fs.WalkDir(Files, "templates", func(path string, d fs.DirEntry, err error) error {
96
+
err = fs.WalkDir(p.embedFS, "templates", func(path string, d fs.DirEntry, err error) error {
if !strings.HasSuffix(path, "html") {
// Skip fragments as they've already been loaded
if strings.Contains(path, "fragments/") {
if strings.Contains(path, "layouts/") {
name := strings.TrimPrefix(path, "templates/")
name = strings.TrimSuffix(name, ".html")
// Add the page template on top of the base
allPaths = append(allPaths, "templates/layouts/*.html")
···
allPaths = append(allPaths, path)
tmpl, err := template.New(name).
116
-
ParseFS(Files, allPaths...)
123
+
ParseFS(p.embedFS, allPaths...)
return fmt.Errorf("setting up template: %w", err)
log.Printf("loaded template: %s", name)
···
log.Printf("total templates loaded: %d", len(templates))
139
+
// loadTemplateFromDisk loads a template from the filesystem in dev mode
140
+
func (p *Pages) loadTemplateFromDisk(name string) error {
136
-
type LoginParams struct {
145
+
log.Printf("reloading template from disk: %s", name)
147
+
// Find all fragments first
148
+
var fragmentPaths []string
149
+
err := filepath.WalkDir(filepath.Join(p.templateDir, "templates"), func(path string, d fs.DirEntry, err error) error {
156
+
if !strings.HasSuffix(path, ".html") {
159
+
if !strings.Contains(path, "fragments/") {
162
+
fragmentPaths = append(fragmentPaths, path)
166
+
return fmt.Errorf("walking disk template dir for fragments: %w", err)
169
+
// Find the template path on disk
170
+
templatePath := filepath.Join(p.templateDir, "templates", name+".html")
171
+
if _, err := os.Stat(templatePath); os.IsNotExist(err) {
172
+
return fmt.Errorf("template not found on disk: %s", name)
175
+
// Create a new template
176
+
tmpl := template.New(name).Funcs(funcMap())
179
+
layoutGlob := filepath.Join(p.templateDir, "templates", "layouts", "*.html")
180
+
layouts, err := filepath.Glob(layoutGlob)
182
+
return fmt.Errorf("finding layout templates: %w", err)
185
+
// Create paths for parsing
186
+
allFiles := append(layouts, fragmentPaths...)
187
+
allFiles = append(allFiles, templatePath)
189
+
// Parse all templates
190
+
tmpl, err = tmpl.ParseFiles(allFiles...)
192
+
return fmt.Errorf("parsing template files: %w", err)
195
+
// Update the template in the map
197
+
log.Printf("template reloaded from disk: %s", name)
func (p *Pages) execute(name string, w io.Writer, params any) error {
140
-
return p.t[name].ExecuteTemplate(w, "layouts/base", params)
202
+
// In dev mode, reload the template from disk before executing
204
+
if err := p.loadTemplateFromDisk(name); err != nil {
205
+
log.Printf("warning: failed to reload template %s from disk: %v", name, err)
206
+
// Continue with the existing template
210
+
tmpl, exists := p.t[name]
212
+
return fmt.Errorf("template not found: %s", name)
215
+
return tmpl.ExecuteTemplate(w, "layouts/base", params)
func (p *Pages) executePlain(name string, w io.Writer, params any) error {
···
func (p *Pages) executeRepo(name string, w io.Writer, params any) error {
return p.t[name].ExecuteTemplate(w, "layouts/repobase", params)
226
+
type LoginParams struct {
func (p *Pages) Login(w io.Writer, params LoginParams) error {
···
func (p *Pages) Static() http.Handler {
876
+
return http.StripPrefix("/static/", http.FileServer(http.Dir("appview/pages/static")))
sub, err := fs.Sub(Files, "static")
log.Fatalf("no static dir found? that's crazy: %v", err)