hugolib: Fix newly created shortcodes not found during server rebuild

When a new shortcode file was added during `hugo server`, the shortcode
was detected but not properly registered in the template cache. This caused
subsequent content edits using the shortcode to fail with "template for
shortcode not found" until the server was restarted.

The issue was that when a shortcode was added, only a glob identity for
dependent content was added to the changes list, but not the shortcode
file's own pathInfo. This meant RefreshFiles filtered it out and never
inserted it into the shortcodesByName cache.

The fix adds the shortcode file's pathInfo to changes (in addition to the
glob for dependent content), and corrects the glob pattern from
`shortcodes/...` to `/_shortcodes/...` to match the actual path format.

Fixes #14207
This commit is contained in:
Rohan Hasabe
2026-01-11 12:00:23 -05:00
committed by Bjørn Erik Pedersen
parent eb06a3cd0c
commit 66ba63cd5f
2 changed files with 39 additions and 1 deletions
+3 -1
View File
@@ -1034,7 +1034,9 @@ func (h *HugoSites) processPartialFileEvents(ctx context.Context, l logg.LevelLo
changes = append(changes, identity.GenghisKhan)
}
if strings.Contains(base, "shortcodes") {
changes = append(changes, hglob.NewGlobIdentity(fmt.Sprintf("shortcodes/%s*", pathInfo.BaseNameNoIdentifier())))
// Add both the shortcode file itself (for template refresh) and a glob for dependent content
changes = append(changes, pathInfo)
changes = append(changes, hglob.NewGlobIdentity(fmt.Sprintf("/_shortcodes/%s*", pathInfo.BaseNameNoIdentifier())))
} else {
changes = append(changes, pathInfo)
}
+36
View File
@@ -2093,3 +2093,39 @@ All.
b.EditFileReplaceAll("content/mybundle/resource.txt", "This is a resource file.", "This is an edited resource file.").Build()
b.AssertFileContent("public/mybundle/resource.txt", "This is an edited resource file.")
}
// Issue #14207
func TestRebuildAddShortcodeThenEditContentUsingIt(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
baseURL = "https://example.com"
disableLiveReload = true
-- layouts/single.html --
Single: {{ .Title }}|{{ .Content }}|
-- content/p1.md --
---
title: "P1"
---
Content before shortcode.
`
b := TestRunning(t, files)
b.AssertFileContent("public/p1/index.html", "Single: P1|", "Content before shortcode.")
// Add a new shortcode file
b.AddFiles(
"layouts/_shortcodes/year.html", `{{- now.Format "2006" -}}`,
).Build()
// Verify shortcode was registered
ts := b.H.Sites[0].Deps.TemplateStore
if ti := ts.LookupShortcodeByName("year"); ti == nil {
t.Fatal("shortcode 'year' not found in cache after adding")
}
// Now edit content to use the shortcode - this should find the shortcode
currentYear := time.Now().Format("2006")
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))
}