From c48551677c2504e3f2d7fa53ee42766e0333b957 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Wed, 8 Apr 2026 12:07:37 +0200 Subject: [PATCH] Fix panic on edit of legacy mapped template names that's also a valid path in the new setup This mapping was added in Hugo `v0.146.0`. Fixes #14740 --- hugolib/rebuild_test.go | 15 +++++++++++++++ tpl/tplimpl/templates.go | 10 +++++----- tpl/tplimpl/templatestore.go | 12 ++++++------ 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/hugolib/rebuild_test.go b/hugolib/rebuild_test.go index 537c00cef..b3f36d442 100644 --- a/hugolib/rebuild_test.go +++ b/hugolib/rebuild_test.go @@ -2126,3 +2126,18 @@ Content before shortcode. b.EditFileReplaceAll("content/p1.md", "Content before shortcode.", "This is {{< year >}} wow.").Build() b.AssertFileContent("public/p1/index.html", "Single: P1|", fmt.Sprintf("This is %s wow.", currentYear)) } + +// Issue 14740. +func TestRebuildEditTagsListLayout(t *testing.T) { + files := ` +-- hugo.toml -- +baseURL = "https://example.com" +-- layouts/tags/list.html -- +Foo. +` + + b := TestRunning(t, files) + b.AssertFileContent("public/tags/index.html", "Foo.") + b.EditFileReplaceAll("layouts/tags/list.html", "Foo", "Bar").Build() + b.AssertFileContent("public/tags/index.html", "Bar.") +} diff --git a/tpl/tplimpl/templates.go b/tpl/tplimpl/templates.go index 043d4a491..be6487b28 100644 --- a/tpl/tplimpl/templates.go +++ b/tpl/tplimpl/templates.go @@ -45,8 +45,8 @@ var embeddedTemplatesAliases = map[string][]string{ "_shortcodes/twitter.html": {"_shortcodes/tweet.html"}, } -func (s *TemplateStore) parseTemplate(ti *TemplInfo, replace bool) error { - err := s.tns.doParseTemplate(ti, replace) +func (s *TemplateStore) parseTemplate(ti *TemplInfo) error { + err := s.tns.doParseTemplate(ti) if err != nil { return s.addFileContext(ti, "parse of template failed", err) } @@ -69,7 +69,7 @@ func (t *templateNamespace) newBlankTemplate(ti *TemplInfo) tpl.Template { return tt } -func (t *templateNamespace) doParseTemplate(ti *TemplInfo, replace bool) error { +func (t *templateNamespace) doParseTemplate(ti *TemplInfo) error { if !ti.noBaseOf || ti.category == CategoryBaseof { // Delay parsing until we have the base template. return nil @@ -84,7 +84,7 @@ func (t *templateNamespace) doParseTemplate(ti *TemplInfo, replace bool) error { if ti.D.IsPlainText { prototype := t.parseText - if !replace && prototype.Lookup(name) != nil { + if prototype.Lookup(name) != nil { name += "-" + strconv.FormatUint(t.nameCounter.Add(1), 10) } templ, err = prototype.New(name).Parse(ti.content) @@ -93,7 +93,7 @@ func (t *templateNamespace) doParseTemplate(ti *TemplInfo, replace bool) error { } } else { prototype := t.parseHTML - if !replace && prototype.Lookup(name) != nil { + if prototype.Lookup(name) != nil { name += "-" + strconv.FormatUint(t.nameCounter.Add(1), 10) } templ, err = prototype.New(name).Parse(ti.content) diff --git a/tpl/tplimpl/templatestore.go b/tpl/tplimpl/templatestore.go index 57a0c4f69..0c324fd84 100644 --- a/tpl/tplimpl/templatestore.go +++ b/tpl/tplimpl/templatestore.go @@ -149,7 +149,7 @@ func NewStore(opts StoreOptions, siteOpts SiteOptions) (*TemplateStore, error) { if err := s.insertEmbedded(); err != nil { return nil, err } - if err := s.parseTemplates(false); err != nil { + if err := s.parseTemplates(); err != nil { return nil, err } if err := s.extractInlinePartials(false); err != nil { @@ -740,7 +740,7 @@ func (s *TemplateStore) RefreshFiles(include func(fi hugofs.FileMetaInfo) bool) if err := s.createTemplatesSnapshot(); err != nil { return err } - if err := s.parseTemplates(true); err != nil { + if err := s.parseTemplates(); err != nil { return err } if err := s.extractInlinePartials(true); err != nil { @@ -1627,7 +1627,7 @@ func (s *TemplateStore) addTransformedTemplateSetTree(this *TemplInfo, root *par return tree, nil } -func (s *TemplateStore) parseTemplates(replace bool) error { +func (s *TemplateStore) parseTemplates() error { if err := func() error { // Read and parse all templates. for _, v := range s.treeMain.All() { @@ -1635,7 +1635,7 @@ func (s *TemplateStore) parseTemplates(replace bool) error { if vv.state == processingStateTransformed { continue } - if err := s.parseTemplate(vv, replace); err != nil { + if err := s.parseTemplate(vv); err != nil { return err } } @@ -1655,7 +1655,7 @@ func (s *TemplateStore) parseTemplates(replace bool) error { // The regular expression used to detect if a template needs a base template has some // rare false positives. Assume we don't need one. vv.noBaseOf = true - if err := s.parseTemplate(vv, replace); err != nil { + if err := s.parseTemplate(vv); err != nil { return err } continue @@ -1684,7 +1684,7 @@ func (s *TemplateStore) parseTemplates(replace bool) error { if vvv.state == processingStateTransformed { continue } - if err := s.parseTemplate(vvv, replace); err != nil { + if err := s.parseTemplate(vvv); err != nil { return err } } -- 2.39.5