]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Set cascade target to the content matrix if not set in the cascade itself
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 28 Dec 2025 12:18:15 +0000 (13:18 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 28 Dec 2025 21:30:55 +0000 (22:30 +0100)
Fixes #14310

Co-authored-by: Joe Mooring <joe.mooring@veriphor.com>
hugolib/cascade_test.go
hugolib/hugo_smoke_test.go
resources/page/page_matcher.go

index fa8e5e4345e4c4ae3135dd902dab02c40a205439..0df3af64cd36d4431ad7b36c3b8945cffc6c6435 100644 (file)
@@ -365,3 +365,48 @@ Resource: {{ .Name }}|p1: {{ .Params.p1 }}|
 
        b.AssertFileContent("public/b1/index.html", "Title: b1|p1: v1|", "Resource: p2.md|p1: v1|")
 }
+
+// Issue 14310
+func TestCascadeIssue14310(t *testing.T) {
+       t.Parallel()
+
+       files := `
+-- hugo.toml --
+disableKinds = ['home','rss','sitemap','taxonomy','term']
+defaultContentLanguage = 'en'
+defaultContentLanguageInSubdir = true
+[languages.en]
+weight = 1
+[languages.de]
+weight = 2
+-- layouts/all.html --
+{{ .Params.color }}
+-- content/s1/_index.de.md --
+---
+title: s1 (de)
+cascade:
+  params:
+    color: red (de)
+---
+-- content/s1/_index.en.md --
+---
+title: s1 (en)
+cascade:
+  params:
+    color: red (en)
+---
+-- content/s1/p1.de.md --
+---
+title: p1 (de)
+---
+-- content/s1/p1.en.md --
+---
+title: p1 (en)
+---
+`
+
+       b := Test(t, files)
+
+       b.AssertFileContent("public/en/s1/p1/index.html", "red (en)")
+       b.AssertFileContent("public/de/s1/p1/index.html", "red (de)") // fails: file contains "red (en)"
+}
index 52424985633fcbfb08588cb7301ac0c1ed3fdf53..bf6d2594932de81dc8ac83b180bc3968541ca871 100644 (file)
@@ -544,7 +544,7 @@ Content Tag 1.
 
        b.AssertFileContent("public/en/posts/p1/index.html",
                "Single: en|page|/en/posts/p1/|Post 1|<p>Content 1.</p>\n|Len Resources: 2|",
-               "Resources: text|/en/posts/p1/f1.txt|text/plain|map[icon:enicon] - page||application/octet-stream|map[background:post.jpg draft:false iscjklanguage:false title:Post Sub 1] -",
+               "Resources: text|/en/posts/p1/f1.txt|text/plain|map[icon:enicon] - page||application/octet-stream|map[draft:false iscjklanguage:false title:Post Sub 1] -",
                "Icon: enicon",
                "Icon fingerprinted: enicon|/en/posts/p1/f1.e5746577af5cbfc4f34c558051b7955a9a5a795a84f1c6ab0609cb3473a924cb.txt|",
                "NextInSection: |\nPrevInSection: /en/posts/p2/|Post 2|",
index 60f0c46547eab31a3f3fa71c206338958ae8ab89..163a91e902f904b8d7129c40a41334d12d059e0d 100644 (file)
@@ -246,8 +246,8 @@ func (d cascadeConfigDecoder) decodePageMatcher(m any, v *PageMatcher) error {
 }
 
 // DecodeCascadeConfigOptions
-func (v *PageMatcher) compileSitesMatrix(configuredDimensions *sitesmatrix.ConfiguredDimensions) error {
-       if v.Sites.Matrix.IsZero() {
+func (v *PageMatcher) compileSitesMatrix(defaults sitesmatrix.VectorStore, configuredDimensions *sitesmatrix.ConfiguredDimensions) error {
+       if v.Sites.Matrix.IsZero() && defaults == nil {
                // Nothing to do.
                v.SitesMatrixCompiled = nil
                return nil
@@ -255,8 +255,12 @@ func (v *PageMatcher) compileSitesMatrix(configuredDimensions *sitesmatrix.Confi
        intSetsCfg := sitesmatrix.IntSetsConfig{
                Globs: v.Sites.Matrix,
        }
-       b := sitesmatrix.NewIntSetsBuilder(configuredDimensions).WithConfig(intSetsCfg).WithAllIfNotSet()
 
+       b := sitesmatrix.NewIntSetsBuilder(configuredDimensions).WithConfig(intSetsCfg)
+       if defaults != nil && v.Sites.Matrix.IsZero() {
+               b = b.WithDimensionsFromOtherIfNotSet(defaults)
+       }
+       b = b.WithAllIfNotSet()
        v.SitesMatrixCompiled = b.Build()
        return nil
 }
@@ -281,6 +285,17 @@ func (p *PageMatcherParamsConfig) init() error {
        return nil
 }
 
+func (p *PageMatcherParamsConfig) hasSitesMatrix() bool {
+       if m, ok := p.Fields["sites"]; ok {
+               mm := maps.ToStringMap(m)
+               if sm, found := mm["matrix"]; found {
+                       mmm := maps.ToStringMap(sm)
+                       return len(mmm) > 0
+               }
+       }
+       return false
+}
+
 type PageMatcherParamsConfigs struct {
        c []*config.ConfigNamespace[[]PageMatcherParamsConfig, CascadeConfig]
 }
@@ -347,16 +362,23 @@ func (c *PageMatcherParamsConfigs) SourceHash() uint64 {
        return h.Sum64()
 }
 
-func (c *PageMatcherParamsConfigs) InitConfig(logger loggers.Logger, _ sitesmatrix.VectorStore, configuredDimensions *sitesmatrix.ConfiguredDimensions) error {
+func (c *PageMatcherParamsConfigs) InitConfig(logger loggers.Logger, defaultsIn sitesmatrix.VectorStore, configuredDimensions *sitesmatrix.ConfiguredDimensions) error {
        if c == nil {
                return nil
        }
        for _, cc := range c.c {
                for i := range cc.Config.Cascades {
-                       checkCascadePattern(logger, cc.Config.Cascades[i].Target)
-                       if err := cc.Config.Cascades[i].Target.compileSitesMatrix(configuredDimensions); err != nil {
+                       ccc := cc.Config.Cascades[i]
+                       checkCascadePattern(logger, ccc.Target)
+                       defaults := defaultsIn
+                       hasSitesMatrix := ccc.hasSitesMatrix()
+                       if hasSitesMatrix {
+                               defaults = nil
+                       }
+                       if err := ccc.Target.compileSitesMatrix(defaults, configuredDimensions); err != nil {
                                return fmt.Errorf("failed to compile cascade target %d: %w", i, err)
                        }
+                       cc.Config.Cascades[i] = ccc
                }
        }
        return nil