mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-24 15:28:54 +00:00
Expand the numeric conversions to template funcs/methods
So the example mentioned in #14079 also works for TOML and JSON front matter. See #14079
This commit is contained in:
@@ -315,6 +315,7 @@ func IsContextType(tp reflect.Type) bool {
|
|||||||
// This is currently only implemented for int kinds,
|
// This is currently only implemented for int kinds,
|
||||||
// added to handle the move to a new YAML library which produces uint64 for unsigned integers.
|
// added to handle the move to a new YAML library which produces uint64 for unsigned integers.
|
||||||
// We can expand on this later if needed.
|
// We can expand on this later if needed.
|
||||||
|
// This conversion is lossless.
|
||||||
// See Issue 14079.
|
// See Issue 14079.
|
||||||
func ConvertIfPossible(val reflect.Value, typ reflect.Type) (reflect.Value, bool) {
|
func ConvertIfPossible(val reflect.Value, typ reflect.Type) (reflect.Value, bool) {
|
||||||
if IsInt(typ.Kind()) {
|
if IsInt(typ.Kind()) {
|
||||||
@@ -333,6 +334,21 @@ func ConvertIfPossible(val reflect.Value, typ reflect.Type) (reflect.Value, bool
|
|||||||
}
|
}
|
||||||
return val.Convert(typ), true
|
return val.Convert(typ), true
|
||||||
}
|
}
|
||||||
|
if IsFloat(val.Kind()) {
|
||||||
|
f := val.Float()
|
||||||
|
if f < float64(math.MinInt64) || f > float64(math.MaxInt64) {
|
||||||
|
return reflect.Value{}, false
|
||||||
|
}
|
||||||
|
i := int64(f)
|
||||||
|
if typ.OverflowInt(i) {
|
||||||
|
return reflect.Value{}, false
|
||||||
|
}
|
||||||
|
// Check for lossless conversion.
|
||||||
|
if float64(i) != f {
|
||||||
|
return reflect.Value{}, false
|
||||||
|
}
|
||||||
|
return val.Convert(typ), true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return reflect.Value{}, false
|
return reflect.Value{}, false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,6 +231,33 @@ func TestCastIfPossible(t *testing.T) {
|
|||||||
ok: true,
|
ok: true,
|
||||||
expected: int(math.MaxInt16),
|
expected: int(math.MaxInt16),
|
||||||
},
|
},
|
||||||
|
// From float to int.
|
||||||
|
{
|
||||||
|
name: "float64(1.5) to int",
|
||||||
|
value: float64(1.5),
|
||||||
|
typ: int(0),
|
||||||
|
ok: false, // loss of precision
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "float64(1.0) to int",
|
||||||
|
value: float64(1.0),
|
||||||
|
typ: int(0),
|
||||||
|
ok: true,
|
||||||
|
expected: int(1),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "float64(math.MaxFloat64) to int16",
|
||||||
|
value: float64(math.MaxFloat64),
|
||||||
|
typ: int16(0),
|
||||||
|
ok: false, // overflow
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "float64(32767) to int16",
|
||||||
|
value: float64(32767),
|
||||||
|
typ: int16(0),
|
||||||
|
ok: true,
|
||||||
|
expected: int16(32767),
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
|
|
||||||
v, ok := ConvertIfPossible(reflect.ValueOf(test.value), reflect.TypeOf(test.typ))
|
v, ok := ConvertIfPossible(reflect.ValueOf(test.value), reflect.TypeOf(test.typ))
|
||||||
|
|||||||
@@ -327,11 +327,53 @@ myinteger: 2
|
|||||||
-- layouts/all.html --
|
-- layouts/all.html --
|
||||||
{{ $date := "2023-10-15T13:18:50-07:00" | time }}
|
{{ $date := "2023-10-15T13:18:50-07:00" | time }}
|
||||||
{{ $mydata := resources.Get "mydata.yaml" | transform.Unmarshal }}
|
{{ $mydata := resources.Get "mydata.yaml" | transform.Unmarshal }}
|
||||||
date: {{ $date | time.Format "2006-01-06" }}|
|
date: {{ $date | time.Format "2006-01-02" }}|
|
||||||
date+2y: {{ $date.AddDate $mydata.myinteger 0 0 | time.Format "2006-01-06" }}|
|
date+2y: {{ $date.AddDate $mydata.myinteger 0 0 | time.Format "2006-01-02" }}|
|
||||||
`
|
`
|
||||||
|
|
||||||
b := hugolib.Test(t, files)
|
b := hugolib.Test(t, files)
|
||||||
|
|
||||||
b.AssertFileContent("public/index.html", "date: 2023-10-23|", "date+2y: 2025-10-25|")
|
b.AssertFileContent("public/index.html", "date: 2023-10-15", "date+2y: 2025-10-15")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTOMLAddDateIssue14079(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
files := `
|
||||||
|
-- hugo.toml --
|
||||||
|
disableKinds = ["page", "section", "taxonomy", "term", "sitemap", "RSS"]
|
||||||
|
-- assets/mydata.toml --
|
||||||
|
myinteger = 2
|
||||||
|
-- layouts/all.html --
|
||||||
|
{{ $date := "2023-10-15T13:18:50-07:00" | time }}
|
||||||
|
{{ $mydata := resources.Get "mydata.toml" | transform.Unmarshal }}
|
||||||
|
date: {{ $date | time.Format "2006-01-02" }}|
|
||||||
|
date+2y: {{ $date.AddDate $mydata.myinteger 0 0 | time.Format "2006-01-02" }}|
|
||||||
|
`
|
||||||
|
|
||||||
|
b := hugolib.Test(t, files)
|
||||||
|
|
||||||
|
b.AssertFileContent("public/index.html", "date: 2023-10-15", "date+2y: 2025-10-15")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJSONAddDateIssue14079(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
files := `
|
||||||
|
-- hugo.toml --
|
||||||
|
disableKinds = ["page", "section", "taxonomy", "term", "sitemap", "RSS"]
|
||||||
|
-- assets/mydata.json --
|
||||||
|
{
|
||||||
|
"myinteger": 2
|
||||||
|
}
|
||||||
|
-- layouts/all.html --
|
||||||
|
{{ $date := "2023-10-15T13:18:50-07:00" | time }}
|
||||||
|
{{ $mydata := resources.Get "mydata.json" | transform.Unmarshal }}
|
||||||
|
date: {{ $date | time.Format "2006-01-02" }}|
|
||||||
|
date+2y: {{ $date.AddDate $mydata.myinteger 0 0 | time.Format "2006-01-02" }}|
|
||||||
|
`
|
||||||
|
|
||||||
|
b := hugolib.Test(t, files)
|
||||||
|
|
||||||
|
b.AssertFileContent("public/index.html", "date: 2023-10-15", "date+2y: 2025-10-15")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user