shithub: hugo

Download patch

ref: 57adc539fc98dcb6fba8070b9611b8bd545f6f7f
parent: b277cb33e4dfa7440fca3b7888026944ce056154
author: Lucas Jenss <[email protected]>
date: Wed Sep 27 20:35:47 EDT 2017

tpl: Add float template function

Add a template function that allows conversion to float. This is
useful, for example, when passing aspect ratios into templates,
which tend to not be integers.

Fixes #3307

--- /dev/null
+++ b/docs/content/functions/float.md
@@ -1,0 +1,26 @@
+---
+title: float
+linktitle: float
+description: Creates a `float` from the argument passed into the function.
+godocref:
+date: 2017-09-28
+publishdate: 2017-09-28
+lastmod: 2017-09-28
+categories: [functions]
+menu:
+  docs:
+    parent: "functions"
+keywords: [strings,floats]
+signature: ["float INPUT"]
+workson: []
+hugoversion:
+relatedfuncs: []
+deprecated: false
+aliases: []
+---
+
+Useful for turning strings into floating point numbers.
+
+```
+{{ float "1.23" }} → 1.23
+```
--- a/tpl/cast/cast.go
+++ b/tpl/cast/cast.go
@@ -30,6 +30,22 @@
 
 // ToInt converts the given value to an int.
 func (ns *Namespace) ToInt(v interface{}) (int, error) {
+	v = convertTemplateToString(v)
+	return _cast.ToIntE(v)
+}
+
+// ToString converts the given value to a string.
+func (ns *Namespace) ToString(v interface{}) (string, error) {
+	return _cast.ToStringE(v)
+}
+
+// ToFloat converts the given value to a float.
+func (ns *Namespace) ToFloat(v interface{}) (float64, error) {
+	v = convertTemplateToString(v)
+	return _cast.ToFloat64E(v)
+}
+
+func convertTemplateToString(v interface{}) interface{} {
 	switch vv := v.(type) {
 	case template.HTML:
 		v = string(vv)
@@ -42,10 +58,5 @@
 	case template.JSStr:
 		v = string(vv)
 	}
-	return _cast.ToIntE(v)
-}
-
-// ToString converts the given value to a string.
-func (ns *Namespace) ToString(v interface{}) (string, error) {
-	return _cast.ToStringE(v)
+	return v
 }
--- a/tpl/cast/cast_test.go
+++ b/tpl/cast/cast_test.go
@@ -81,3 +81,40 @@
 		assert.Equal(t, test.expect, result, errMsg)
 	}
 }
+
+func TestToFloat(t *testing.T) {
+	t.Parallel()
+
+	ns := New()
+
+	for i, test := range []struct {
+		v      interface{}
+		expect interface{}
+	}{
+		{"1", 1.0},
+		{template.HTML("2"), 2.0},
+		{template.CSS("3"), 3.0},
+		{template.HTMLAttr("4"), 4.0},
+		{template.JS("-5.67"), -5.67},
+		{template.JSStr("6"), 6.0},
+		{"1.23", 1.23},
+		{"-1.23", -1.23},
+		{"0", 0.0},
+		{float64(2.12), 2.12},
+		{int64(123), 123.0},
+		{2, 2.0},
+		{t, false},
+	} {
+		errMsg := fmt.Sprintf("[%d] %v", i, test.v)
+
+		result, err := ns.ToFloat(test.v)
+
+		if b, ok := test.expect.(bool); ok && !b {
+			require.Error(t, err, errMsg)
+			continue
+		}
+
+		require.NoError(t, err, errMsg)
+		assert.Equal(t, test.expect, result, errMsg)
+	}
+}
--- a/tpl/cast/init.go
+++ b/tpl/cast/init.go
@@ -43,6 +43,13 @@
 			},
 		)
 
+		ns.AddMethodMapping(ctx.ToFloat,
+			[]string{"float"},
+			[][2]string{
+				{`{{ "1234" | float | printf "%T" }}`, `float64`},
+			},
+		)
+
 		return ns
 
 	}