Repository: gohugoio/hugo (language: go)

Issue:
Cascade property affects the next page with similar name
### What version of Hugo are you using (`hugo version`)?
<pre>
$ hugo v0.122.0-b9a03bd59d5f71a529acb3e33f995e0ef332b3aa+extended windows/amd64
</pre>

**Tested versions:**
Hugo extended windows-amd64 versions 0.123.0 - 0.125.6


### Does this issue reproduce with the latest release?
Yes

### Bug description
**Cascade property affects the next page with similar name.**
We use cascade in one of our pages _(/team)_ to prevent rendering its children separately. But the cascade property affects the next following page _(/teams)_.

### File setup
/content
├ /de
│├ /...
│├ **/team** _(List of our employees)_
││├ /employee_1
│││└ index.md
││├ /...
││└  **_index.md**
│├ **/teams** _(Articles about Microsoft Teams)_
││├ /article_1
│││└ index.md
││├ /...
││└ **_index.md**
│├ /...
...

### Code
**/content/de/team/_index.md:**
``` YML
...
cascade:
    _build:
        render: never
_build:
    render: always
---
```

### Tests
1. Renaming the folder "/teams" to "/xteams"
→ "/xteams" was rendered
2. Put the same cascade properties pages where the next page had an similar name
→ E.g. cascade properties were added to "/microsoft" and the next page ("microsoft-365") wasn't rendered anymore

### Conclusion
Cascade should only affect children of an page.
→ /page/...
But cascade affect every page where the name starts with the name of the page with the cascade properties.
→ /page...



Discussion / hints:
This problem was introduced in v0.123.0. Failing test:

```go
func TestFoo(t *testing.T) {
	t.Parallel()

	files := `
-- hugo.toml --
disableKinds = ['home','rss','sitemap','taxonomy','term']
-- layouts/_default/list.html --
{{ .Title }}
-- layouts/_default/single.html --
{{ .Title }}
-- content/s/_index.md --
---
title: s
cascade:
  _build:
    render: never
---
-- content/s/p1.md --
---
title: p1
---
-- content/sx/_index.md --
---
title: sx
---
-- content/sx/p2.md --
---
title: p2
---
`

	b := hugolib.Test(t, files)

	b.AssertFileExists("public/s/index.html", false)
	b.AssertFileExists("public/s/p1/index.html", false)

	b.AssertFileExists("public/sx/index.html", true)    // failing
	b.AssertFileExists("public/sx/p2/index.html", true) // failing
}
```
@tobias-sundermann 

You can work around this by removing the cascade from matter, and specify the cascade in your site configuration instead:

```text
[[cascade]]
[cascade.build]
render = 'never'
[cascade._target]
path = '{/s,/s/**}'
```

This will suppress rendering of all pages in the given section, including the section page itself.


@mapangalee a progress will be indicated by e.g. a PR referencing this issue or that this issue is marked as closed/solved.

Please don't edit your comment to make the notification to reappear in my feed. While that technically works, it's not particulary motivating.

Fix patch:
diff --git a/hugolib/content_map_page.go b/hugolib/content_map_page.go
index 6927562f127..b930845e58b 100644
--- a/hugolib/content_map_page.go
+++ b/hugolib/content_map_page.go
@@ -1397,7 +1397,7 @@ func (sa *sitePagesAssembler) applyAggregates() error {
 				pw.WalkContext.Data().Insert(keyPage, cascade)
 			}
 		} else {
-			_, data := pw.WalkContext.Data().LongestPrefix(keyPage)
+			_, data := pw.WalkContext.Data().LongestPrefix(paths.Dir(keyPage))
 			if data != nil {
 				cascade = data.(*maps.Ordered[page.PageMatcher, maps.Params])
 			}


Test patch:
diff --git a/hugolib/cascade_test.go b/hugolib/cascade_test.go
index 47e53d9277f..f3060814c00 100644
--- a/hugolib/cascade_test.go
+++ b/hugolib/cascade_test.go
@@ -876,3 +876,44 @@ Background: {{ .Params.background }}|
 		b.AssertFileContent("public/p1/index.html", "Background: yosemite.jpg")
 	}
 }
+
+// Issue #12465.
+func TestCascadeOverlap(t *testing.T) {
+	t.Parallel()
+
+	files := `
+-- hugo.toml --
+disableKinds = ['home','rss','sitemap','taxonomy','term']
+-- layouts/_default/list.html --
+{{ .Title }}
+-- layouts/_default/single.html --
+{{ .Title }}
+-- content/s/_index.md --
+---
+title: s
+cascade:
+  _build:
+    render: never
+---
+-- content/s/p1.md --
+---
+title: p1
+---
+-- content/sx/_index.md --
+---
+title: sx
+---
+-- content/sx/p2.md --
+---
+title: p2
+---
+`
+
+	b := Test(t, files)
+
+	b.AssertFileExists("public/s/index.html", false)
+	b.AssertFileExists("public/s/p1/index.html", false)
+
+	b.AssertFileExists("public/sx/index.html", true)    // failing
+	b.AssertFileExists("public/sx/p2/index.html", true) // failing
+}