-
Notifications
You must be signed in to change notification settings - Fork 106
5. Advanced Customization
There are a few primitives in Jet that you can use to improve performance or handle certain objects a little differently when it comes to rendering them into a template or iterating over them:
- fast functions by implementing a function with the signature
func(jet.Arguments) reflect.Value
- custom iterator by implementing the interface
jet.Ranger
- custom renderer by implementing the interface
jet.Renderer
- custom escape handling by implementing a
SafeWriter
function with the signaturefunc(io.Writer, []byte)
Each of these will now be explained with an example.
var views = jet.NewHTMLSet("./views")
views.AddGlobalFunc("base64", func(a jet.Arguments) reflect.Value {
a.RequireNumOfArguments("base64", 1, 1)
buffer := bytes.NewBuffer(nil)
fmt.Fprint(buffer, a.Get(0))
return reflect.ValueOf(base64.URLEncoding.EncodeToString(buffer.Bytes()))
})
Tell Jet how many arguments your function is supposed to take (pass -1 for min/max if they are 0 or unlimited) – it will panic with a descriptive error message if used incorrectly in a template. Via a.Get(index)
you may request an argument by its index.
An example of this is in the example project, see the main.go.
type tTODO struct {
Text string
Done bool
}
// Render implements jet.Renderer interface
func (t *tTODO) Render(r *jet.Runtime) {
done := "yes"
if !t.Done {
done = "no"
}
r.Write([]byte(fmt.Sprintf("TODO: %s (done: %s)", t.Text, done)))
}
An example of this is in the example project, see the main.go.
When you're taking advantage of Jet's auto-escaping a SafeWriter
function is passed upon instantiation of the jet.Set
, the default created with jet.NewHTMLSet("your/views/directory")
is Go's template.HTMLEscape
function. Escape functions get the writer and the bytes to be written as parameters. If you want to disable auto-escaping or handle it in a special way you may provide a custom escape function like this:
func RawWriter(w io.Writer, b []byte) {
w.Write(b)
}
var views = jet.NewSet(jet.SafeWriter(RawWriter), "./views")
The other way to use custom escape functions is to use them as filters in your templates. The core library does this in the same way because both the raw
and the unsafe
filters are custom escape functions (take a look into the default.go file). Adding your own is easy:
var views = jet.NewHTMLSet("./views")
views.AddGlobal("specialEscape", jet.SafeWriter(func(w io.Writer, b []byte) {
// special escape handling
// then write your bytes into the writer:
w.Write(b)
}))
Use it in your templates as filters:
{{ "funky user-generated content in need of escaping"|specialEscape }}
{{ specialEscape: "funky user-generated content in need of escaping" }}
As explained in the pipelines section escape functions need to be the last statement when chaining or there cannot be any more filters when using the prefix version.