Add date and tz functions to templates (#3812)
* Add date and tz functions to templates This commit adds the date and tz functions to templates. This means users can now format time in a specified format and also change the timezone to their specific locale. An example of how these functions work, and can be composed together, can be seen here: {{ .StartsAt | tz "Europe/Paris" | date "15:04:05 MST" }} Signed-off-by: George Robinson <george.robinson@grafana.com> --------- Signed-off-by: George Robinson <george.robinson@grafana.com>
This commit is contained in:
parent
cb9724db47
commit
dc1e1a2b88
|
@ -95,3 +95,5 @@ templating.
|
|||
| join | sep string, s []string | [strings.Join](http://golang.org/pkg/strings/#Join), concatenates the elements of s to create a single string. The separator string sep is placed between elements in the resulting string. (note: argument order inverted for easier pipelining in templates.) |
|
||||
| safeHtml | text string | [html/template.HTML](https://golang.org/pkg/html/template/#HTML), Marks string as HTML not requiring auto-escaping. |
|
||||
| stringSlice | ...string | Returns the passed strings as a slice of strings. |
|
||||
| date | string, time.Time | Returns the text representation of the time in the specified format. For documentation on formats refer to [pkg.go.dev/time](https://pkg.go.dev/time#pkg-constants). |
|
||||
| tz | string, time.Time | Returns the time in the timezone. For example, Europe/Paris. |
|
||||
|
|
|
@ -192,6 +192,18 @@ var DefaultFuncs = FuncMap{
|
|||
"stringSlice": func(s ...string) []string {
|
||||
return s
|
||||
},
|
||||
// date returns the text representation of the time in the specified format.
|
||||
"date": func(fmt string, t time.Time) string {
|
||||
return t.Format(fmt)
|
||||
},
|
||||
// tz returns the time in the timezone.
|
||||
"tz": func(name string, t time.Time) (time.Time, error) {
|
||||
loc, err := time.LoadLocation(name)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
return t.In(loc), nil
|
||||
},
|
||||
}
|
||||
|
||||
// Pair is a key/value string pair.
|
||||
|
|
|
@ -473,10 +473,11 @@ func TestTemplateFuncs(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
for _, tc := range []struct {
|
||||
title string
|
||||
in string
|
||||
data interface{}
|
||||
exp string
|
||||
title string
|
||||
in string
|
||||
data interface{}
|
||||
exp string
|
||||
expErr string
|
||||
}{{
|
||||
title: "Template using toUpper",
|
||||
in: `{{ "abc" | toUpper }}`,
|
||||
|
@ -506,6 +507,21 @@ func TestTemplateFuncs(t *testing.T) {
|
|||
title: "Template using reReplaceAll",
|
||||
in: `{{ reReplaceAll "ab" "AB" "abc" }}`,
|
||||
exp: "ABc",
|
||||
}, {
|
||||
title: "Template using date",
|
||||
in: `{{ . | date "2006-01-02" }}`,
|
||||
data: time.Date(2024, 1, 1, 8, 15, 30, 0, time.UTC),
|
||||
exp: "2024-01-01",
|
||||
}, {
|
||||
title: "Template using tz",
|
||||
in: `{{ . | tz "Europe/Paris" }}`,
|
||||
data: time.Date(2024, 1, 1, 8, 15, 30, 0, time.UTC),
|
||||
exp: "2024-01-01 09:15:30 +0100 CET",
|
||||
}, {
|
||||
title: "Template using invalid tz",
|
||||
in: `{{ . | tz "Invalid/Timezone" }}`,
|
||||
data: time.Date(2024, 1, 1, 8, 15, 30, 0, time.UTC),
|
||||
expErr: "template: :1:7: executing \"\" at <tz \"Invalid/Timezone\">: error calling tz: unknown time zone Invalid/Timezone",
|
||||
}} {
|
||||
tc := tc
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
|
@ -515,8 +531,13 @@ func TestTemplateFuncs(t *testing.T) {
|
|||
go func() {
|
||||
defer wg.Done()
|
||||
got, err := tmpl.ExecuteTextString(tc.in, tc.data)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.exp, got)
|
||||
if tc.expErr == "" {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.exp, got)
|
||||
} else {
|
||||
require.EqualError(t, err, tc.expErr)
|
||||
require.Empty(t, got)
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
|
|
Loading…
Reference in New Issue