Browse Source

Added TODO notes for theme support and correct VFS for theming. See


Warning: This commit breaks a few things but should work as expected for
simpler use cases. For efforts to use theming while simultaneously using
the default file system loader that wraps Pongo2's built-in loader, this
will likely no longer function as expected.

What we need to do is refactor a substantial portion of this code such
that we can have greater control over where files are being loaded from.
This appears to be potentially easier than I expected when I wrote the
TODO (modifying the Get() behavior in PongoVFSLoader is probably all we
need to do), but I'd like to remove any reliance on the default loader
and force it to use our VFS implementation.

The advantage to this is that we can remove some code and simplify a few
use cases. This means it wouldn't be necessary in default cases to use
the VFS layer, or sensible defaults could be opted for instead, which
would obviate most of the VFS configuration entirely. Then, for more
interesting or customized use cases, we could expose an easier-to-use
API that allows users to attach VFS instances directly instead of
wrapping them via VFS' integration collection (thereby no longer
requiring users to build the collection themselves).
Benjamin Shelton 9 months ago
1 changed files with 33 additions and 3 deletions
  1. +33

+ 33
- 3
render/pongo2.go View File

@ -17,6 +17,28 @@ import (
// TODO: (Big.)
// In order to support on-demand template theme changes, we need to be able to
// use a single tmeplate root and modify subdirectories (or the root, as an
// example) either per request or per template loader. At present, this isn't
// possible to do without reloading the application since both Pongo2's default
// loader would require reinitialization, and the VFS layer is set during
// renderer creation time.
// What we probably ought to do is force Pongo2 to use only the VFS layer/loader
// rather than falling back to Pongo2's built-in loader(s) which would limit the
// scope of what we need to change. Then, we could provide or expose a function
// that would allow changing the VFS root directories dynamically.
// Additionally, we could expand the API to allow changing the template via the
// Renderer interface or, temporarily, via the ContextRenderer interface--which
// conveniently is used to provide some limited isolation.
// In order to do this, we would probably need to expose the Pongo2 loaders by
// wrapping the library or otherwise doing something to make it so the loaders
// could be temporarily extended per-request.
type MapValues = pongo2.Context
// Loaders returns a slice of pongo2.TemplateLoaders for use in PongoOptions
@ -420,11 +442,16 @@ type NotifyLoader interface {
type InheritanceLoader struct{}
type PongoVFSLoader struct {
fs vfs.FileSystem
// TODO: See notes at top level of file.
fs vfs.FileSystem
theme string
func NewPongoVFSLoader(fs vfs.FileSystem) pongo2.TemplateLoader {
return &PongoVFSLoader{fs: fs}
func NewPongoVFSLoader(opts *Options) pongo2.TemplateLoader {
return &PongoVFSLoader{
theme: opts.ThemePath,
fs: opts.VFS,
func (l *PongoVFSLoader) Abs(base, name string) string {
@ -432,6 +459,9 @@ func (l *PongoVFSLoader) Abs(base, name string) string {
func (l *PongoVFSLoader) Get(path string) (io.Reader, error) {
if len(l.theme) != 0 {
path = filepath.Join(l.theme, path)
return l.fs.Open(path)