diff --git a/hugolib/frontmatter_test.go b/hugolib/frontmatter_test.go new file mode 100644 index 000000000..ade779c38 --- /dev/null +++ b/hugolib/frontmatter_test.go @@ -0,0 +1,47 @@ +// Copyright 2022 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" + +// Issue 10624 +func TestFrontmatterPreserveDatatypesForSlices(t *testing.T) { + t.Parallel() + + files := ` +-- content/post/one.md -- +--- +ints: [1, 2, 3] +mixed: ["1", 2, 3] +strings: ["1", "2","3"] +--- +-- layouts/_default/single.html -- +Ints: {{ printf "%T" .Params.ints }} {{ range .Params.ints }}Int: {{ fmt.Printf "%[1]v (%[1]T)" . }}|{{ end }} +Mixed: {{ printf "%T" .Params.mixed }} {{ range .Params.mixed }}Mixed: {{ fmt.Printf "%[1]v (%[1]T)" . }}|{{ end }} +Strings: {{ printf "%T" .Params.strings }} {{ range .Params.strings }}Strings: {{ fmt.Printf "%[1]v (%[1]T)" . }}|{{ end }} +` + b := NewIntegrationTestBuilder( + IntegrationTestConfig{ + T: t, + TxtarString: files, + }, + ) + + b.Build() + + b.AssertFileContent("public/post/one/index.html", "Ints: []interface {} Int: 1 (int)|Int: 2 (int)|Int: 3 (int)|") + b.AssertFileContent("public/post/one/index.html", "Mixed: []interface {} Mixed: 1 (string)|Mixed: 2 (int)|Mixed: 3 (int)|") + b.AssertFileContent("public/post/one/index.html", "Strings: []string Strings: 1 (string)|Strings: 2 (string)|Strings: 3 (string)|") + +} diff --git a/hugolib/page__meta.go b/hugolib/page__meta.go index 8d2495ddc..bb038a1d9 100644 --- a/hugolib/page__meta.go +++ b/hugolib/page__meta.go @@ -579,41 +579,30 @@ func (pm *pageMeta) setMetadata(parentBucket *pagesMapBucket, p *pageState, fron default: // If not one of the explicit values, store in Params switch vv := v.(type) { - case bool: - pm.params[loki] = vv - case string: - pm.params[loki] = vv - case int64, int32, int16, int8, int: - pm.params[loki] = vv - case float64, float32: - pm.params[loki] = vv - case time.Time: - pm.params[loki] = vv - default: // handle array of strings as well - switch vvv := vv.(type) { - case []any: - if len(vvv) > 0 { - switch vvv[0].(type) { - case map[any]any: - pm.params[loki] = vvv - case map[string]any: - pm.params[loki] = vvv - case []any: - pm.params[loki] = vvv - default: - a := make([]string, len(vvv)) - for i, u := range vvv { - a[i] = cast.ToString(u) - } - - pm.params[loki] = a + case []any: + if len(vv) > 0 { + allStrings := true + for _, vvv := range vv { + if _, ok := vvv.(string); !ok { + allStrings = false + break } - } else { - pm.params[loki] = []string{} } - default: - pm.params[loki] = vv + if allStrings { + // We need tags, keywords etc. to be []string, not []interface{}. + a := make([]string, len(vv)) + for i, u := range vv { + a[i] = cast.ToString(u) + } + pm.params[loki] = a + } else { + pm.params[loki] = vv + } + } else { + pm.params[loki] = []string{} } + default: + pm.params[loki] = vv } } }