"github.com/fsnotify/fsnotify"
"github.com/gohugoio/hugo/common/herrors"
"github.com/gohugoio/hugo/common/hugo"
+ "github.com/gohugoio/hugo/common/paths"
"github.com/gohugoio/hugo/langs"
"github.com/gohugoio/hugo/tpl/tplimpl"
if f.c.fastRenderMode && f.c.errState.buildErr() == nil {
if isNavigation(requestURI, r) {
+ // See issue 14240.
+ // Hugo escapes the URL paths when generating them,
+ // that may not be the case when we receive it back from the browser.
+ // PathEscape will escape if it is not already escaped.
+ requestURI = paths.PathEscape(requestURI)
+
if !f.c.visitedURLs.Contains(requestURI) {
// If not already on stack, re-render that single page.
if err := f.c.partialReRender(requestURI); err != nil {
}
})
}
+
+func TestPathEscape(t *testing.T) {
+ c := qt.New(t)
+
+ for _, this := range []struct {
+ input string
+ expected string
+ }{
+ {"/tags/欢迎", "/tags/%E6%AC%A2%E8%BF%8E"},
+ {"/path with spaces", "/path%20with%20spaces"},
+ {"/simple-path", "/simple-path"},
+ {"/path/with/slash", "/path/with/slash"},
+ {"/path/with special&chars", "/path/with%20special&chars"},
+ } {
+ in := this.input
+ for range 2 {
+ result := PathEscape(in)
+ c.Assert(result, qt.Equals, this.expected, qt.Commentf("input: %q", this.input))
+ in = result // test idempotency
+ }
+ }
+}
b.AssertFileContent("public/tags/index.html", "All. Tag1|$")
}
+func TestRebuildPageWithChineseTag14240(t *testing.T) {
+ t.Parallel()
+
+ files := `
+-- hugo.toml --
+baseURL = "https://example.com"
+disableLiveReload = true
+-- layouts/all.html --
+All. {{ range .Pages }}{{ .RelPermalink }}: {{ .Title }}|{{ end }}$
+-- content/p1.md --
+---
+title: "P1"
+tags: ["欢迎"]
+---
+
+`
+ b := TestRunning(t, files)
+
+ b.AssertFileContent("public/tags/欢迎/index.html", "All. /p1/: P1|$")
+ b.EditFileReplaceAll("content/p1.md", "P1", "P1 edit").Build()
+ b.AssertFileContent("public/tags/欢迎/index.html", "All. /p1/: P1 edit|$")
+}
+
func TestRebuildEditNonReferencedResourceIssue13748(t *testing.T) {
t.Parallel()
// httpget checks that a HTTP resource's body matches (if it compiles as a regexp) or contains all of the strings given as arguments.
"httpget": func(ts *testscript.TestScript, neg bool, args []string) {
if len(args) < 2 {
- ts.Fatalf("usage: httpgrep URL STRING...")
+ ts.Fatalf("usage: httpget URL STRING...")
}
tryget := func() error {
// The server will write a .ready file when ready.
// We wait for that.
readyFilename := ts.MkAbs(".ready")
- limit := time.Now().Add(5 * time.Second)
+ limit := time.Now().Add(10 * time.Second)
for {
_, err := os.Stat(readyFilename)
if err != nil {
--- /dev/null
+# Issue 14240.
+
+hugo server &
+
+waitServer
+
+httpget ${HUGOTEST_BASEURL_0}tags/%E6%AC%A2%E8%BF%8E/ '_P1_'
+
+replace $WORK/content/p1.md 'P1' 'P1 New'
+
+httpget ${HUGOTEST_BASEURL_0}tags/%E6%AC%A2%E8%BF%8E/ '_P1 New_'
+
+stopServer
+! stderr .
+
+-- hugo.toml --
+baseURL = "https://example.com"
+disableLiveReload = true
+-- layouts/all.html --
+All. {{ range .Pages }}_{{ .Title }}_{{ end }}$
+-- content/p1.md --
+---
+title: "P1"
+tags: ["欢迎"]
+---