diff --git a/appview/pages/funcmap.go b/appview/pages/funcmap.go index 38f1b359..3b1f9e4b 100644 --- a/appview/pages/funcmap.go +++ b/appview/pages/funcmap.go @@ -526,14 +526,16 @@ func (p *Pages) AvatarUrl(actor, size string) string { signature := hex.EncodeToString(h.Sum(nil)) // Get avatar CID for cache busting - profile, err := db.GetProfile(p.db, did) version := "" - if err == nil && profile != nil && profile.Avatar != "" { - // Use first 8 chars of avatar CID as version - if len(profile.Avatar) > 8 { - version = profile.Avatar[:8] - } else { - version = profile.Avatar + if p.db != nil { + profile, err := db.GetProfile(p.db, did) + if err == nil && profile != nil && profile.Avatar != "" { + // Use first 8 chars of avatar CID as version + if len(profile.Avatar) > 8 { + version = profile.Avatar[:8] + } else { + version = profile.Avatar + } } } diff --git a/appview/pages/pages.go b/appview/pages/pages.go index 775bd212..731f81c3 100644 --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -88,6 +88,65 @@ func (p *Pages) nameToPath(s string) string { return "templates/" + s + ".html" } +// FuncMap returns the template function map for use by external template consumers. +func (p *Pages) FuncMap() template.FuncMap { + return p.funcMap() +} + +// FragmentPaths returns all fragment template paths from the embedded FS. +func (p *Pages) FragmentPaths() ([]string, error) { + return p.fragmentPaths() +} + +// EmbedFS returns the embedded filesystem containing templates and static assets. +func (p *Pages) EmbedFS() fs.FS { + return p.embedFS +} + +// ParseWith parses the base layout together with all appview fragments and +// an additional template from extraFS identified by extraPath (relative to +// extraFS root). The returned template is ready to ExecuteTemplate with +// "layouts/base" -- primarily for use with the blog. +func (p *Pages) ParseWith(extraFS fs.FS, extraPath string) (*template.Template, error) { + fragmentPaths, err := p.fragmentPaths() + if err != nil { + return nil, err + } + + funcs := p.funcMap() + tpl, err := template.New("layouts/base"). + Funcs(funcs). + ParseFS(p.embedFS, append(fragmentPaths, p.nameToPath("layouts/base"))...) + if err != nil { + return nil, err + } + + err = fs.WalkDir(extraFS, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if d.IsDir() || !strings.HasSuffix(path, ".html") { + return nil + } + if path != extraPath && !strings.Contains(path, "fragments/") { + return nil + } + data, err := fs.ReadFile(extraFS, path) + if err != nil { + return err + } + if _, err = tpl.New(path).Parse(string(data)); err != nil { + return err + } + return nil + }) + if err != nil { + return nil, err + } + + return tpl, nil +} + func (p *Pages) fragmentPaths() ([]string, error) { var fragmentPaths []string err := fs.WalkDir(p.embedFS, "templates", func(path string, d fs.DirEntry, err error) error {