In a Go template, sometimes the way to pass the right data to the right template feels awkward to me. Calling a template with a pipeline parameter looks like calling a function with only one parameter.
Let's say I have a site for Gophers about Gophers. It has a home page main template, and a utility template to print a list of Gophers.
http://play.golang.org/p/Jivy_WPh16
Output :
*The great GopherBook* (logged in as Dewey)
[Most popular]
>> Huey
>> Dewey
>> Louie
[Most active]
>> Huey
>> Louie
[Most recent]
>> Louie
Now I want to add a bit of context in the subtemplate : format the name "Dewey" differently inside the list because it's the name of the currently logged user. But I can't pass the name directly because there is only one possible "dot" argument pipeline! What can I do?
- Obviously I can copy-paste the subtemplate code into the main template (I don't want to because it drops all the interest of having a subtemplate).
- Or I can juggle with some kind of global variables with accessors (I don't want to either).
- Or I can create a new specific struct type for each template parameter list (not great).
The best i've found so far (and I don't really like it) is muxing and demuxing parameters with a "generic" pair container :
http://play.golang.org/p/ri3wMAubPX
I use this trick a lot for building my website, and I wonder if there exist some more idiomatic way to achieve the same.
You can define functions in your template, and have these functions being closures defined on your data like this:
Then, you can simply call this function in your template:
This updated version on the playground outputs pretty
!!
around the current user:EDIT
Since you can override functions when calling
Funcs
, you can actually pre-populate the template functions when compiling your template, and update them with your actual closure like this:Although I am not sure how that plays when several goroutines try to access the same template...
The working example
I implemented a library for this issue which supports pipe-like arguments passing&check.
Demo
Github repo