Have you ever wanted to pass multiple arguments to a go sub-template? If you google it you'll be convinced it's not possible. But bear with me.
In go templates you can pass a single "argument" (pipeline in go parlance) to a "sub-template" defined block. But by creating a simple helper function you can pass as many arguments as you want. Simply add this function to your FuncMap
:
func(els ...any) []any {
return els
}
And you'll be able to create constructs such as:
{{ template "MyTemplate" (arr "first" 123 .Some.Value) }}
{{ template "MyTemplate" (arr "second" 456 .Other.Value) }}
{{ define "MyTeplate" }}
{{ $strArg := index . 0 }}
{{ $intArg := index . 1 }}
{{ $valArg := index . 2 }}
This is my str {{ $strArg }} parameter.
...
{{ end }}
I named arr
my helper func, but you can call it whatever you want.
Enjoy!
Top comments (8)
With Go templates it's much more preferable to define a struct containing the data you wish to expose to the template, for example,
and in your template you would have something like,
this provides a more stricter mechanism by which to control what data is in a template, and more clarity too since you would be referring to the data via the field names. Furthermore, it provides some type checking beforehand via the struct's fields.
Agreed. But eventually in the rare case when you need a more dynamic approach now you know how.
In the case of having a more dynamic approach I would then prefer
map[string]any
.Actually we're talking about different things.
The example you showed is related to data sent from Go to the template.
My post is about a template calling a sub-template.
Imagine an html form builder, where each field is constructed by calling a sub template:
The data sent from Go to the template is a struct (MP3 info), field names have nothing to do with the MP3 data, they're a frontend issue.
In that case I would simply change your implementation to not use an
arr
function for grabbing arbitrary values and still use a map. See the playground link for an example as to what I mean: go.dev/play/p/5Hiajt4H2Z5A
map
function is defined which takes the pairs of values and puts them into amap[string]any
, these can then be accessed from the sub-template. This provides more clarity of the data being accessed since the values can be referred to by the index name.This is very helpful thanks for that!
Nice! This was really helping me. However, it needs to be:
{{ template "MyTemplate" (els "first" 123 .Some.Value) }}
{{ template "MyTemplate" (els "second" 456 .Other.Value) }}
In the end I wrote: “I named arr my helper func, but you can call it whatever you want.”,
els
is the name of the arguments. The name of the function you define on your FuncMap: