Bug: Inferred type of frontmatter list is wrong for mixed strings and maps

(By map, I technically mean maps.Params.)

When a list starts with a string, the type of the list is inferred to be []string:

authors:
- nick
- name: nick

Here, the second value is "", since it must be a string.

When it starts with a map, the type of the list is inferred to be []interface{}:

authors:
- name: nick
- nick

Here, the type of the first element is map, and the type of the second is string.

It should always infer []interface{} based on all the element types. If any element is a map, the type should be []interface{}.

Edit 1: Forgot to include this:

$ hugo env
hugo v0.108.0+extended darwin/amd64 BuildDate=unknown
GOOS="darwin"
GOARCH="amd64"
GOVERSION="go1.19.3"
github.com/sass/libsass="3.6.5"
github.com/webmproject/libwebp="v1.2.4"

Edit 2: This happens with custom frontmatter parameters like “foo”, not just “authors”.

1 Like

I agree with you; this seems broken. It’s not anything new (I tested back to v0.54.0).

Front matter:

example_1:
- 1
- foo
- true
example_2:
- a: 1
- b: foo
- c: true
example_3:
- 1
- 2
- 3

Example 1

{{ range .Params.example_1 }}
  {{ fmt.Printf "%[1]v (%[1]T)" . }}
{{ end }}

Actual:   1 (string) foo (string) true (string)
Expected: 1 (int) foo (string) true (bool)

Example 2

{{ range .Params.example_2 }}
  {{ range . }}
    {{ fmt.Printf "%[1]v (%[1]T)" . }}
  {{ end }}
{{ end }}

Actual:   1 (int) foo (string) true (bool)
Expected: 1 (int) foo (string) true (bool)

Example 3

{{ range .Params.example_3 }}
  {{ fmt.Printf "%[1]v (%[1]T)" . }}
{{ end }}

Actual:   1 (string) 2 (string) 3 (string)
Expected: 1 (int) 2 (int) 3 (int)

I suppose you could make a case that Example 1 should throw an error due to mixed types, but clearly Example 3 is incorrect. The transform.Unmarshal template function does the right thing:

{{ $t := `s: [1,2,3]` }}
{{ range (transform.Unmarshal $t).s }}
  {{ fmt.Printf "%[1]v (%[1]T)" . }}
{{ end }}

--> 1 (int) 2 (int) 3 (int)

The front matter format (JSON, TOML, or YAML) is irrelevant.

https://github.com/gohugoio/hugo/issues/10624

2 Likes

I had similar problems. Thanks for investigating and clarifying the problem.

1 Like

@jmooring Should I create a GH issue for this?

See above. Looks like it’s already fixed.

1 Like

With https://github.com/gohugoio/hugo/pull/10625

example_1:
- 1
- foo
- true
example_2:
- a: 1
- b: foo
- c: true
example_3:
- 1
- 2
- 3
authors:
- name: nick
- nick
1 (int) foo (string) true (bool)
1 (int) foo (string) true (bool)
1 (int) 2 (int) 3 (int)
map[name:nick] (map[string]interface {}) nick (string)
3 Likes

@bep @jmooring Thanks for the fix! :rocket:

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.