Decouple TemplateFunc from templ.Component by introducing a generic HTMLComponent interface that both templ and pongo2 satisfy via Go structural typing. Add a complete pongo2 rendering engine in templates/pongo/ with page templates, block templates (with BlockContext injection and icon processing), template overrides, and email wrappers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
44 lines
906 B
Go
44 lines
906 B
Go
package pongo
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"io/fs"
|
|
|
|
"github.com/flosch/pongo2/v6"
|
|
)
|
|
|
|
// fsLoader adapts an fs.FS to pongo2's TemplateLoader interface.
|
|
type fsLoader struct {
|
|
fsys fs.FS
|
|
}
|
|
|
|
func (l *fsLoader) Abs(base, name string) string {
|
|
return name
|
|
}
|
|
|
|
func (l *fsLoader) Get(path string) (io.Reader, error) {
|
|
return l.fsys.Open(path)
|
|
}
|
|
|
|
// multiLoader chains multiple loaders, returning the first hit.
|
|
// Plugin templates can {% extends "base.html" %} where base.html
|
|
// lives in the core embedded FS rather than the plugin FS.
|
|
type multiLoader struct {
|
|
loaders []pongo2.TemplateLoader
|
|
}
|
|
|
|
func (l *multiLoader) Abs(base, name string) string {
|
|
return name
|
|
}
|
|
|
|
func (l *multiLoader) Get(path string) (io.Reader, error) {
|
|
for _, loader := range l.loaders {
|
|
r, err := loader.Get(path)
|
|
if err == nil {
|
|
return r, nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("pongo: template %q not found in any loader", path)
|
|
}
|