From a99665fea65c26c6cd2e1882d274e2b02b1ebb3f Mon Sep 17 00:00:00 2001 From: Sebastian Winkler Date: Fri, 27 Apr 2018 16:29:16 +0200 Subject: [PATCH 1/4] adds ability to define custom funcs in LocalizeConfig --- v2/i18n/localizer.go | 7 ++++++- v2/internal/message_template.go | 6 ++++-- v2/internal/template.go | 4 ++-- v2/internal/template_test.go | 4 ++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/v2/i18n/localizer.go b/v2/i18n/localizer.go index 41dc9503..1e5dc00d 100644 --- a/v2/i18n/localizer.go +++ b/v2/i18n/localizer.go @@ -3,6 +3,8 @@ package i18n import ( "fmt" + "text/template" + "github.com/nicksnyder/go-i18n/v2/internal" "github.com/nicksnyder/go-i18n/v2/internal/plural" "golang.org/x/text/language" @@ -56,6 +58,9 @@ type LocalizeConfig struct { // DefaultMessage is used if the message is not found in any message files. DefaultMessage *Message + + // Funcs is used to extend the Go template engines built in functions + Funcs template.FuncMap } type invalidPluralCountErr struct { @@ -114,7 +119,7 @@ func (l *Localizer) Localize(lc *LocalizeConfig) (string, error) { if pluralForm == plural.Invalid { return "", &pluralizeErr{messageID: messageID, tag: tag} } - return template.Execute(pluralForm, templateData) + return template.Execute(pluralForm, templateData, lc.Funcs) } func (l *Localizer) getTemplate(id string, defaultMessage *Message) (language.Tag, *internal.MessageTemplate) { diff --git a/v2/internal/message_template.go b/v2/internal/message_template.go index f28d014d..03aed6f3 100644 --- a/v2/internal/message_template.go +++ b/v2/internal/message_template.go @@ -3,6 +3,8 @@ package internal import ( "bytes" + "text/template" + "github.com/nicksnyder/go-i18n/v2/internal/plural" ) @@ -37,9 +39,9 @@ func setPluralTemplate(pluralTemplates map[plural.Form]*Template, pluralForm plu } // Execute executes the template for the plural form and template data. -func (mt *MessageTemplate) Execute(pluralForm plural.Form, data interface{}) (string, error) { +func (mt *MessageTemplate) Execute(pluralForm plural.Form, data interface{}, funcs template.FuncMap) (string, error) { t := mt.PluralTemplates[pluralForm] - if err := t.parse(mt.LeftDelim, mt.RightDelim); err != nil { + if err := t.parse(mt.LeftDelim, mt.RightDelim, funcs); err != nil { return "", err } if t.Template == nil { diff --git a/v2/internal/template.go b/v2/internal/template.go index 90b0cfcb..2ef1eeac 100644 --- a/v2/internal/template.go +++ b/v2/internal/template.go @@ -12,10 +12,10 @@ type Template struct { ParseErr *error } -func (t *Template) parse(leftDelim, rightDelim string) error { +func (t *Template) parse(leftDelim, rightDelim string, funcs gotemplate.FuncMap) error { if t.ParseErr == nil { if strings.Contains(t.Src, leftDelim) { - gt, err := gotemplate.New("").Delims(leftDelim, rightDelim).Parse(t.Src) + gt, err := gotemplate.New("").Funcs(funcs).Delims(leftDelim, rightDelim).Parse(t.Src) t.Template = gt t.ParseErr = &err } else { diff --git a/v2/internal/template_test.go b/v2/internal/template_test.go index 7af17224..f3873a1f 100644 --- a/v2/internal/template_test.go +++ b/v2/internal/template_test.go @@ -7,7 +7,7 @@ import ( func TestParse(t *testing.T) { tmpl := &Template{Src: "hello"} - if err := tmpl.parse("", ""); err != nil { + if err := tmpl.parse("", "", nil); err != nil { t.Fatal(err) } if tmpl.ParseErr == nil { @@ -21,7 +21,7 @@ func TestParse(t *testing.T) { func TestParseError(t *testing.T) { expectedErr := fmt.Errorf("expected error") tmpl := &Template{ParseErr: &expectedErr} - if err := tmpl.parse("", ""); err != expectedErr { + if err := tmpl.parse("", "", nil); err != expectedErr { t.Fatalf("expected %#v; got %#v", expectedErr, err) } } From 2d1d9c435b56c4959c6a07eaf757127e3dc961a0 Mon Sep 17 00:00:00 2001 From: Sebastian Winkler Date: Fri, 27 Apr 2018 16:55:18 +0200 Subject: [PATCH 2/4] adds TestParseWithFunc --- v2/internal/template_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/v2/internal/template_test.go b/v2/internal/template_test.go index f3873a1f..cae5351d 100644 --- a/v2/internal/template_test.go +++ b/v2/internal/template_test.go @@ -3,6 +3,7 @@ package internal import ( "fmt" "testing" + "text/template" ) func TestParse(t *testing.T) { @@ -25,3 +26,21 @@ func TestParseError(t *testing.T) { t.Fatalf("expected %#v; got %#v", expectedErr, err) } } + +func TestParseWithFunc(t *testing.T) { + tmpl := &Template{Src: "hello"} + funcs := template.FuncMap{ + "foo": func() string { + return "bar" + }, + } + if err := tmpl.parse("", "", funcs); err != nil { + t.Fatal(err) + } + if tmpl.ParseErr == nil { + t.Fatal("expected non-nil parse error") + } + if tmpl.Template == nil { + t.Fatal("expected non-nil template") + } +} From 154f1dcbd0d89aaa2d839f004489920641cfe431 Mon Sep 17 00:00:00 2001 From: Sebastian Winkler Date: Fri, 27 Apr 2018 18:26:51 +0200 Subject: [PATCH 3/4] fixes TestParseWithFunc --- v2/internal/template_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2/internal/template_test.go b/v2/internal/template_test.go index cae5351d..f83616b0 100644 --- a/v2/internal/template_test.go +++ b/v2/internal/template_test.go @@ -28,7 +28,7 @@ func TestParseError(t *testing.T) { } func TestParseWithFunc(t *testing.T) { - tmpl := &Template{Src: "hello"} + tmpl := &Template{Src: "{{foo}}"} funcs := template.FuncMap{ "foo": func() string { return "bar" From 306150fa5f86d4823c2c9b8758f5958469b1740a Mon Sep 17 00:00:00 2001 From: Sebastian Winkler Date: Sat, 28 Apr 2018 00:20:56 +0200 Subject: [PATCH 4/4] improves TestParseWithFunc --- v2/internal/template_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/v2/internal/template_test.go b/v2/internal/template_test.go index f83616b0..68e60d0e 100644 --- a/v2/internal/template_test.go +++ b/v2/internal/template_test.go @@ -1,6 +1,7 @@ package internal import ( + "bytes" "fmt" "testing" "text/template" @@ -43,4 +44,11 @@ func TestParseWithFunc(t *testing.T) { if tmpl.Template == nil { t.Fatal("expected non-nil template") } + var buf bytes.Buffer + if tmpl.Template.Execute(&buf, nil) != nil { + t.Fatal("expected nil template execute error") + } + if buf.String() != "bar" { + t.Fatalf("expected bar; got %s", buf.String()) + } }