The problem is that your filter function does not accept or return the right types to match what pongo2 is requiring. Let's walk through the docs and see what they want.
First, take a look at the godoc for RegisterFilterFunction
. It says
func RegisterFilter(name string, fn FilterFunction)
This is in the pongo2
package so you should read this as RegisterFilter
is a function that accepts two arguments and returns no values. The first argument name
is of the builtin type string
and the second argument fn
is of the type pongo2.FilterFunction
. But what is a pongo2.FilterFunction
? Well clicking on it we see further down in the doc
type FilterFunction func(in *Value, param *Value) (out *Value, err *Error)
In Go you can make your own types based on any other types including functions. So what pongo2 has done is to create a named type called FilterFunction
that is any func which accepts two arguments (both of type *pongo2.Value
) and returns two values (one of type *pongo2.value
and one of type *pongo2.Error
).
To bring it all together we would do something like this:
package main
import (
"fmt"
"log"
"strings"
"github.com/flosch/pongo2"
)
func init() {
pongo2.RegisterFilter("scream", Scream)
}
// Scream is a silly example of a filter function that upper cases strings
func Scream(in *pongo2.Value, param *pongo2.Value) (out *pongo2.Value, err *pongo2.Error) {
if !in.IsString() {
return nil, &pongo2.Error{
ErrorMsg: "only strings should be sent to the scream filter",
}
}
s := in.String()
s = strings.ToUpper(s)
return pongo2.AsValue(s), nil
}
func main() {
tpl, err := pongo2.FromString("Hello {{ name|scream }}!")
if err != nil {
log.Fatal(err)
}
// Now you can render the template with the given
// pongo2.Context how often you want to.
out, err := tpl.Execute(pongo2.Context{"name": "stack overflow"})
if err != nil {
log.Fatal(err)
}
fmt.Println(out) // Output: Hello STACK OVERFLOW!
}