@@ -30,6 +30,7 @@ import (
30
30
"unicode"
31
31
"unicode/utf8"
32
32
33
+ "github.com/gohugoio/hugo/common/maps"
33
34
"github.com/gohugoio/hugo/common/types"
34
35
"github.com/gohugoio/hugo/output/layouts"
35
36
@@ -191,8 +192,10 @@ func newTemplateHandlers(d *deps.Deps) (*tpl.TemplateHandlers, error) {
191
192
192
193
func newTemplateNamespace (funcs map [string ]any ) * templateNamespace {
193
194
return & templateNamespace {
194
- prototypeHTML : htmltemplate .New ("" ).Funcs (funcs ),
195
- prototypeText : texttemplate .New ("" ).Funcs (funcs ),
195
+ prototypeHTML : htmltemplate .New ("" ).Funcs (funcs ),
196
+ prototypeText : texttemplate .New ("" ).Funcs (funcs ),
197
+ prototypeHTMLCloneCache : maps .NewCache [prototypeCloneID , * htmltemplate.Template ](),
198
+ prototypeTextCloneCache : maps .NewCache [prototypeCloneID , * texttemplate.Template ](),
196
199
templateStateMap : & templateStateMap {
197
200
templates : make (map [string ]* templateState ),
198
201
},
@@ -688,7 +691,7 @@ func (t *templateHandler) addTemplateTo(info templateInfo, to *templateNamespace
688
691
func (t * templateHandler ) applyBaseTemplate (overlay , base templateInfo ) (tpl.Template , error ) {
689
692
if overlay .isText {
690
693
var (
691
- templ = t .main .prototypeTextClone .New (overlay .name )
694
+ templ = t .main .getPrototypeText ( prototypeCloneIDBaseof ) .New (overlay .name )
692
695
err error
693
696
)
694
697
@@ -713,7 +716,7 @@ func (t *templateHandler) applyBaseTemplate(overlay, base templateInfo) (tpl.Tem
713
716
}
714
717
715
718
var (
716
- templ = t .main .prototypeHTMLClone .New (overlay .name )
719
+ templ = t .main .getPrototypeHTML ( prototypeCloneIDBaseof ) .New (overlay .name )
717
720
err error
718
721
)
719
722
@@ -953,27 +956,37 @@ func (t *templateHandler) postTransform() error {
953
956
return nil
954
957
}
955
958
959
+ type prototypeCloneID uint16
960
+
961
+ const (
962
+ prototypeCloneIDBaseof prototypeCloneID = iota + 1
963
+ prototypeCloneIDDefer
964
+ )
965
+
956
966
type templateNamespace struct {
957
- prototypeText * texttemplate.Template
958
- prototypeHTML * htmltemplate.Template
959
- prototypeTextClone * texttemplate.Template
960
- prototypeHTMLClone * htmltemplate.Template
967
+ prototypeText * texttemplate.Template
968
+ prototypeHTML * htmltemplate.Template
969
+
970
+ prototypeHTMLCloneCache * maps.Cache [prototypeCloneID , * htmltemplate.Template ]
971
+ prototypeTextCloneCache * maps.Cache [prototypeCloneID , * texttemplate.Template ]
961
972
962
973
* templateStateMap
963
974
}
964
975
965
- func (t * templateNamespace ) getPrototypeText () * texttemplate.Template {
966
- if t .prototypeTextClone != nil {
967
- return t .prototypeTextClone
976
+ func (t * templateNamespace ) getPrototypeText (id prototypeCloneID ) * texttemplate.Template {
977
+ v , ok := t .prototypeTextCloneCache .Get (id )
978
+ if ! ok {
979
+ return t .prototypeText
968
980
}
969
- return t . prototypeText
981
+ return v
970
982
}
971
983
972
- func (t * templateNamespace ) getPrototypeHTML () * htmltemplate.Template {
973
- if t .prototypeHTMLClone != nil {
974
- return t .prototypeHTMLClone
984
+ func (t * templateNamespace ) getPrototypeHTML (id prototypeCloneID ) * htmltemplate.Template {
985
+ v , ok := t .prototypeHTMLCloneCache .Get (id )
986
+ if ! ok {
987
+ return t .prototypeHTML
975
988
}
976
- return t . prototypeHTML
989
+ return v
977
990
}
978
991
979
992
func (t * templateNamespace ) Lookup (name string ) (tpl.Template , bool ) {
@@ -989,9 +1002,10 @@ func (t *templateNamespace) Lookup(name string) (tpl.Template, bool) {
989
1002
}
990
1003
991
1004
func (t * templateNamespace ) createPrototypes () error {
992
- t .prototypeTextClone = texttemplate .Must (t .prototypeText .Clone ())
993
- t .prototypeHTMLClone = htmltemplate .Must (t .prototypeHTML .Clone ())
994
-
1005
+ for _ , id := range []prototypeCloneID {prototypeCloneIDBaseof , prototypeCloneIDDefer } {
1006
+ t .prototypeHTMLCloneCache .Set (id , htmltemplate .Must (t .prototypeHTML .Clone ()))
1007
+ t .prototypeTextCloneCache .Set (id , texttemplate .Must (t .prototypeText .Clone ()))
1008
+ }
995
1009
return nil
996
1010
}
997
1011
@@ -1021,15 +1035,15 @@ func (t *templateNamespace) addDeferredTemplate(owner *templateState, name strin
1021
1035
var templ tpl.Template
1022
1036
1023
1037
if owner .isText () {
1024
- prototype := t .getPrototypeText ()
1038
+ prototype := t .getPrototypeText (prototypeCloneIDDefer )
1025
1039
tt , err := prototype .New (name ).Parse ("" )
1026
1040
if err != nil {
1027
1041
return fmt .Errorf ("failed to parse empty text template %q: %w" , name , err )
1028
1042
}
1029
1043
tt .Tree .Root = n
1030
1044
templ = tt
1031
1045
} else {
1032
- prototype := t .getPrototypeHTML ()
1046
+ prototype := t .getPrototypeHTML (prototypeCloneIDDefer )
1033
1047
tt , err := prototype .New (name ).Parse ("" )
1034
1048
if err != nil {
1035
1049
return fmt .Errorf ("failed to parse empty HTML template %q: %w" , name , err )
0 commit comments