diff options
author | Vas Sudanagunta <vas@commonkarma.org> | 2018-02-11 19:10:49 -0500 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2018-02-12 17:14:40 +0100 |
commit | 1fa2417777d82b81bf37919ad02de4f5dcbf0d50 (patch) | |
tree | 32ea28c273e8f0c66fcaec1df6a7bf3b3a643a31 | |
parent | bb549a0d57505a6b8f28930bb91a9ab44cbb3288 (diff) |
Add support for YAML array data files
* Unmarshaled YAML arrays indistinguishable from JSON arrays.
* Fixes #3890
-rw-r--r-- | hugolib/datafiles_test.go | 60 | ||||
-rw-r--r-- | hugolib/site.go | 2 | ||||
-rw-r--r-- | parser/frontmatter.go | 17 |
3 files changed, 34 insertions, 45 deletions
diff --git a/hugolib/datafiles_test.go b/hugolib/datafiles_test.go index de124a77d..6b66a51eb 100644 --- a/hugolib/datafiles_test.go +++ b/hugolib/datafiles_test.go @@ -95,25 +95,23 @@ func TestDataDirBoolean(t *testing.T) { func TestDataDirTwoFiles(t *testing.T) { t.Parallel() - equivDataDirs := make([]dataDir, 2) + equivDataDirs := make([]dataDir, 3) equivDataDirs[0].addSource("data/test/foo.json", `{ "bar": "foofoo" }`) - equivDataDirs[0].addSource("data/test.json", `{ "hello": [ { "world": "foo" } ] }`) + equivDataDirs[0].addSource("data/test.json", `{ "hello": [ "world", "foo" ] }`) equivDataDirs[1].addSource("data/test/foo.yaml", "bar: foofoo") - equivDataDirs[1].addSource("data/test.yaml", "hello:\n- world: foo") + equivDataDirs[1].addSource("data/test.yaml", "hello:\n- world\n- foo") - // TODO Unresolved Issue #3890 - /* - equivDataDirs[2].addSource("data/test/foo.toml", "bar = \"foofoo\"") - equivDataDirs[2].addSource("data/test.toml", "[[hello]]\nworld = \"foo\"") - */ + equivDataDirs[2].addSource("data/test/foo.toml", "bar = \"foofoo\"") + equivDataDirs[2].addSource("data/test.toml", "hello = [\"world\", \"foo\"]") expected := map[string]interface{}{ "test": map[string]interface{}{ "hello": []interface{}{ - map[string]interface{}{"world": "foo"}, + "world", + "foo", }, "foo": map[string]interface{}{ "bar": "foofoo", @@ -156,54 +154,28 @@ func TestDataDirOverriddenValue(t *testing.T) { doTestEquivalentDataDirs(t, equivDataDirs, expected) } -// Issue #4361 -func TestDataDirJSONArrayAtTopLevelOfFile(t *testing.T) { - t.Parallel() - - var dd dataDir - dd.addSource("data/test.json", `[ { "hello": "world" }, { "what": "time" }, { "is": "lunch?" } ]`) - - expected := - map[string]interface{}{ - "test": []interface{}{ - map[string]interface{}{"hello": "world"}, - map[string]interface{}{"what": "time"}, - map[string]interface{}{"is": "lunch?"}, - }, - } - - doTestDataDir(t, dd, expected) -} - -// TODO Issue #3890 unresolved -func TestDataDirYAMLArrayAtTopLevelOfFile(t *testing.T) { +// Issue #4361, #3890 +func TestDataDirArrayAtTopLevelOfFile(t *testing.T) { t.Parallel() + equivDataDirs := make([]dataDir, 2) - var dd dataDir - dd.addSource("data/test.yaml", ` + equivDataDirs[0].addSource("data/test.json", `[ { "hello": "world" }, { "what": "time" }, { "is": "lunch?" } ]`) + equivDataDirs[1].addSource("data/test.yaml", ` - hello: world - what: time - is: lunch? `) - //TODO decide whether desired structure map[interface {}]interface{} as shown - // and as the YAML parser produces, or should it be map[string]interface{} - // all the way down per Issue #4138 expected := map[string]interface{}{ "test": []interface{}{ - map[interface{}]interface{}{"hello": "world"}, - map[interface{}]interface{}{"what": "time"}, - map[interface{}]interface{}{"is": "lunch?"}, + map[string]interface{}{"hello": "world"}, + map[string]interface{}{"what": "time"}, + map[string]interface{}{"is": "lunch?"}, }, } - // what we are actually getting as of v0.34 - expectedV0_34 := - map[string]interface{}{} - _ = expected - - doTestDataDir(t, dd, expectedV0_34) + doTestEquivalentDataDirs(t, equivDataDirs, expected) } // Issue #892 diff --git a/hugolib/site.go b/hugolib/site.go index d62662814..95cd0a23e 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -870,7 +870,7 @@ func (s *Site) readData(f source.ReadableFile) (interface{}, error) { switch f.Extension() { case "yaml", "yml": - return parser.HandleYAMLMetaData(content) + return parser.HandleYAMLData(content) case "json": return parser.HandleJSONData(content) case "toml": diff --git a/parser/frontmatter.go b/parser/frontmatter.go index c1a57ce5b..5ed3ec11d 100644 --- a/parser/frontmatter.go +++ b/parser/frontmatter.go @@ -216,6 +216,23 @@ func HandleYAMLMetaData(datum []byte) (map[string]interface{}, error) { return m, err } +// HandleYAMLData unmarshals YAML-encoded datum and returns a Go interface +// representing the encoded data structure. +func HandleYAMLData(datum []byte) (interface{}, error) { + var m interface{} + err := yaml.Unmarshal(datum, &m) + + // To support boolean keys, the `yaml` package unmarshals maps to + // map[interface{}]interface{}. Here we recurse through the result + // and change all maps to map[string]interface{} like we would've + // gotten from `json`. + if err == nil { + m = stringifyYAMLMapKeys(m) + } + + return m, err +} + // stringifyKeysMapValue recurses into in and changes all instances of // map[interface{}]interface{} to map[string]interface{}. This is useful to // work around the impedence mismatch between JSON and YAML unmarshaling that's |