Make macros per-template-execution
This commit is contained in:
parent
17906cf329
commit
69e515326f
12
macro_tag.go
12
macro_tag.go
@ -30,17 +30,17 @@ func (mt macroTag) Run(tc *TagContext, block, args []ast.Node) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(block) == 0 {
|
if len(block) == 0 {
|
||||||
tc.t.ns.mu.Lock()
|
tc.t.macroMtx.Lock()
|
||||||
macro, ok := tc.t.ns.macros[name]
|
macro, ok := tc.t.macros[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrNoSuchMacro
|
return ErrNoSuchMacro
|
||||||
}
|
}
|
||||||
tc.t.ns.mu.Unlock()
|
tc.t.macroMtx.Unlock()
|
||||||
return tc.Execute(macro, nil)
|
return tc.Execute(macro, nil)
|
||||||
} else {
|
} else {
|
||||||
tc.t.ns.mu.Lock()
|
tc.t.macroMtx.Lock()
|
||||||
tc.t.ns.macros[name] = block
|
tc.t.macros[name] = block
|
||||||
tc.t.ns.mu.Unlock()
|
tc.t.macroMtx.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
18
namespace.go
18
namespace.go
@ -21,26 +21,22 @@ package salix
|
|||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"go.elara.ws/salix/ast"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Namespace represents a collection of templates that can include each other
|
// Namespace represents a collection of templates that can include each other
|
||||||
type Namespace struct {
|
type Namespace struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
tmpls map[string]*Template
|
tmpls map[string]*Template
|
||||||
vars map[string]reflect.Value
|
vars map[string]reflect.Value
|
||||||
tags map[string]Tag
|
tags map[string]Tag
|
||||||
macros map[string][]ast.Node
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new template namespace
|
// New returns a new template namespace
|
||||||
func New() *Namespace {
|
func New() *Namespace {
|
||||||
return &Namespace{
|
return &Namespace{
|
||||||
tmpls: map[string]*Template{},
|
tmpls: map[string]*Template{},
|
||||||
vars: map[string]reflect.Value{},
|
vars: map[string]reflect.Value{},
|
||||||
tags: map[string]Tag{},
|
tags: map[string]Tag{},
|
||||||
macros: map[string][]ast.Node{},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
salix.go
20
salix.go
@ -24,6 +24,7 @@ import (
|
|||||||
"html"
|
"html"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"go.elara.ws/salix/ast"
|
"go.elara.ws/salix/ast"
|
||||||
)
|
)
|
||||||
@ -61,6 +62,9 @@ type Template struct {
|
|||||||
|
|
||||||
tags map[string]Tag
|
tags map[string]Tag
|
||||||
vars map[string]reflect.Value
|
vars map[string]reflect.Value
|
||||||
|
|
||||||
|
macroMtx sync.Mutex
|
||||||
|
macros map[string][]ast.Node
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithVarMap returns a copy of the template with its variable map set to m.
|
// WithVarMap returns a copy of the template with its variable map set to m.
|
||||||
@ -124,7 +128,21 @@ func (t *Template) WithEscapeHTML(b bool) *Template {
|
|||||||
// Execute executes a parsed template and writes
|
// Execute executes a parsed template and writes
|
||||||
// the result to w.
|
// the result to w.
|
||||||
func (t *Template) Execute(w io.Writer) error {
|
func (t *Template) Execute(w io.Writer) error {
|
||||||
return t.execute(w, t.ast, nil)
|
// Create a new template to give each execution
|
||||||
|
// its own macros
|
||||||
|
tmpl := &Template{
|
||||||
|
ns: t.ns,
|
||||||
|
name: t.name,
|
||||||
|
ast: t.ast,
|
||||||
|
|
||||||
|
escapeHTML: t.escapeHTML,
|
||||||
|
|
||||||
|
tags: t.tags,
|
||||||
|
vars: t.vars,
|
||||||
|
macros: map[string][]ast.Node{},
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpl.execute(w, t.ast, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Template) execute(w io.Writer, nodes []ast.Node, local map[string]any) error {
|
func (t *Template) execute(w io.Writer, nodes []ast.Node, local map[string]any) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user