diff --git a/hugolib/page__meta.go b/hugolib/page__meta.go index 0ffdb0b841c..a549356fd93 100644 --- a/hugolib/page__meta.go +++ b/hugolib/page__meta.go @@ -421,9 +421,20 @@ func (p *pageState) setMetaPostParams() error { var sitemapSet bool var draft, published, isCJKLanguage *bool + var userParams map[string]any for k, v := range pm.params { loki := strings.ToLower(k) + if loki == "params" { + vv, err := maps.ToStringMapE(v) + if err != nil { + return err + } + userParams = vv + delete(pm.params, k) + continue + } + if loki == "published" { // Intentionally undocumented vv, err := cast.ToBoolE(v) if err == nil { @@ -589,6 +600,10 @@ func (p *pageState) setMetaPostParams() error { } } + for k, v := range userParams { + pm.params[strings.ToLower(k)] = v + } + if !sitemapSet { pm.sitemap = p.s.conf.Sitemap } diff --git a/hugolib/params_test.go b/hugolib/params_test.go new file mode 100644 index 00000000000..32b4bd7c339 --- /dev/null +++ b/hugolib/params_test.go @@ -0,0 +1,54 @@ +// Copyright 2024 The Hugo Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hugolib + +import "testing" + +func TestFrontMatterParamsInItsOwnSection(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +baseURL = "https://example.org/" +-- content/_index.md -- ++++ +title = "Home" +[[cascade]] +background = 'yosemite.jpg' +[cascade.params] +a = "home-a" +b = "home-b" +[cascade._target] +kind = 'page' ++++ +-- content/p1.md -- +--- +title: "P1" +summary: "frontmatter.summary" +params: + a: "p1-a" + summary: "params.summary" +--- +-- layouts/_default/single.html -- +Params: {{ range $k, $v := .Params }}{{ $k }}: {{ $v }}|{{ end }}$ +Summary: {{ .Summary }}| +` + + b := Test(t, files) + + b.AssertFileContent("public/p1/index.html", + "Params: a: p1-a|b: home-b|background: yosemite.jpg|draft: false|iscjklanguage: false|summary: params.summary|title: P1|$", + "Summary: frontmatter.summary|", + ) +} diff --git a/resources/page/page_matcher.go b/resources/page/page_matcher.go index f5e8e26970b..8529b0e2810 100644 --- a/resources/page/page_matcher.go +++ b/resources/page/page_matcher.go @@ -144,7 +144,16 @@ func mapToPageMatcherParamsConfig(m map[string]any) (PageMatcherParamsConfig, er // those values will now be moved to the top level. // This should be very unlikely as it would lead to constructs like .Params.params.foo, // and most people see params as an Hugo internal keyword. - pcfg.Params = maps.ToStringMap(v) + params := maps.ToStringMap(v) + if pcfg.Params == nil { + pcfg.Params = params + } else { + for k, v := range params { + if _, found := pcfg.Params[k]; !found { + pcfg.Params[k] = v + } + } + } case "_target", "target": var target PageMatcher if err := decodePageMatcher(v, &target); err != nil {