diff --git a/go/dotprompt/dotprompt.go b/go/dotprompt/dotprompt.go index f02641007..d0ae5a8ec 100644 --- a/go/dotprompt/dotprompt.go +++ b/go/dotprompt/dotprompt.go @@ -159,7 +159,19 @@ func (dp *Dotprompt) DefinePartial(name string, source string, tpl *raymond.Temp return nil } -// TODO(#501): Add register helpers +// RegisterHelper registers a custom helper function for use in templates, +// mirroring the JS implementation's defineHelper API. The helper is applied +// the next time a template is compiled via Compile or Render. +func (dp *Dotprompt) RegisterHelper(name string, helper any) *Dotprompt { + if dp.Helpers == nil { + dp.Helpers = make(map[string]any) + } + dp.Helpers[name] = helper + return dp +} + +// RegisterHelpers applies all pending custom helpers (from RegisterHelper or +// DotpromptOptions.Helpers) plus the built-in template helpers to tpl. func (dp *Dotprompt) RegisterHelpers(tpl *raymond.Template) error { if dp.Helpers != nil { for key, helper := range dp.Helpers { diff --git a/go/dotprompt/dotprompt_test.go b/go/dotprompt/dotprompt_test.go index 1820fa861..d0806167b 100644 --- a/go/dotprompt/dotprompt_test.go +++ b/go/dotprompt/dotprompt_test.go @@ -112,6 +112,42 @@ func TestDefinePartial(t *testing.T) { } } +// TestRegisterHelper tests the public RegisterHelper API for registering a +// custom helper before compiling a template. +func TestRegisterHelper(t *testing.T) { + dp := NewDotprompt(nil) + + shoutHelperFunc := func(s string) string { + return strings.ToUpper(s) + "!" + } + + returned := dp.RegisterHelper("shout", shoutHelperFunc) + if returned != dp { + t.Fatalf("Expected RegisterHelper to return the same *Dotprompt for chaining") + } + + if _, ok := dp.Helpers["shout"]; !ok { + t.Fatalf("Expected helper 'shout' to be present in dp.Helpers") + } + + tpl, err := raymond.Parse("{{shout 'hello'}}") + if err != nil { + t.Fatalf("Failed to parse template: %v", err) + } + + if err = dp.RegisterHelpers(tpl); err != nil { + t.Fatalf("RegisterHelpers failed: %v", err) + } + + result, err := tpl.Exec(nil) + if err != nil { + t.Fatalf("Template execution failed: %v", err) + } + if result != "HELLO!" { + t.Errorf("Expected template output 'HELLO!', got '%s'", result) + } +} + // TestRegisterHelpers tests registering helpers from options and built-ins. func TestRegisterHelpers(t *testing.T) { optionHelperName := "optionHelper"