Skip to content

Commit 67aede4

Browse files
committed
tpl/collections: Make dict return nil when no values are provided
1 parent 87f194b commit 67aede4

3 files changed

Lines changed: 37 additions & 0 deletions

File tree

common/hashing/hashing_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ func TestXxHashFromString(t *testing.T) {
6262
c.Assert(got, qt.Equals, uint64(7148569436472236994))
6363
}
6464

65+
func TestHashNilMapVsEmptyMap(t *testing.T) {
66+
c := qt.New(t)
67+
68+
var m1 map[string]any = nil
69+
m2 := map[string]any{}
70+
71+
c.Assert(HashString(m1), qt.Equals, HashString(m2))
72+
}
73+
6574
func TestXxHashFromStringHexEncoded(t *testing.T) {
6675
c := qt.New(t)
6776
s := "The quick brown fox jumps over the lazy dog"

tpl/collections/collections.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,17 @@ func (ns *Namespace) Delimit(ctx context.Context, l, sep any, last ...any) (stri
157157
// Dictionary creates a new map from the given parameters by
158158
// treating values as key-value pairs. The number of values must be even.
159159
// The keys can be string slices, which will create the needed nested structure.
160+
// If no values are provided, nil will be returned.
160161
func (ns *Namespace) Dictionary(values ...any) (map[string]any, error) {
162+
if len(values) == 0 {
163+
// A common construct is to do
164+
// {{ $opts := dict }}
165+
// And then conditionally assign it if some condition is set.
166+
// The only difference between this and an empty map is that this cannot be written to,
167+
// which is not something we do in Hugo (or: If we do, that's a bug).
168+
// This saves us ~48 bytes in memory allocation on 64-bit architectures.
169+
return nil, nil
170+
}
161171
if len(values)%2 != 0 {
162172
return nil, errors.New("invalid dictionary call")
163173
}

tpl/collections/collections_integration_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,3 +653,21 @@ All.
653653
}
654654
})
655655
}
656+
657+
func TestEmptyDictShouldBeNil(t *testing.T) {
658+
t.Parallel()
659+
660+
files := `
661+
-- hugo.toml --
662+
-- layouts/home.html --
663+
{{ $d := dict }}
664+
{{ printf "dict: %T %t %d" $d (eq $d nil) (len $d) }}
665+
{{ range $d }}FAIL{{ end }}
666+
index: {{ index $d "foo" }}|
667+
{{ $d2 := dict "foo" "bar" }}
668+
{{ $d3 := merge $d $d2 }}
669+
{{ printf "d3: %v" $d3 }}|
670+
`
671+
672+
hugolib.Test(t, files).AssertFileContent("public/index.html", "dict: map[string]interface {} true 0", "! FAIL", "index: |", "d3: map[foo:bar]|")
673+
}

0 commit comments

Comments
 (0)