Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

This is partly a follow-up to my earlier question . The problem I'm trying to solve now is converting Jinja2 macros with arguments, e.g., something like

{% macro example(arg1, arg2) %}
{% if arg1 %}
   do something with arg1 and arg2
{% endif %}
{% endmacro %}

AFAICT, in Go, the nearest equivalent are nested templates, e.g.,

{{define "example"}}
{{if .Arg1}}
    do something with .Arg1 and .Arg2
{{end}}
{{end}}

However, whereas in Jinja arg1 and arg2 are what I'd call true arguments, i.e., when you call the example macro you invoke it as {{example(par1, par2)}}, in Go, you use {{template "example" .}} and the dot is analogous in my mind to an undefined (or not clearly defined) global workspace.

The problem is when those arguments are defined in the calling template, i.e., let's say that in Jinja it's called as {{example("somestring", "another")}} in one template and two other strings in another template. I thought I could use variables to pass the information, e.g., {{$arg1 := "somestring"}} and then invoke the template, or even define the variable in the same action as the invocation, but Go keeps complaining undefined variable "$arg1" so it doesn't seem to be possible.

I know I can "push" the definition of the strings to the calling Go code, but aside from complicating the calling tree, this doesn't feel right because after all the template is presentation code and those strings are part of the presentation, not the business logic. And it's not just string arguments, there are (a) instances of formatting functions (like upper() and lower()--I know I can define them in a funcmap) and (b) HTML formatting macros that, for example, take a CSS class attribute as one of the arguments.

Is there any hope for a solution with Go templates or should I just give up and use something else?

If you want something similar in nature to Jinja2 (though actually modeled off Django) then Pongo2 is a good choice. github.com/flosch/pongo2 – sberry Aug 13, 2019 at 3:16 I wasn't expressly looking for a (more or less) direct replacement for Jinja2, but I guess I'll give Pongo2 a try, since it does look like the path of least resistance. Thanks. – Joe Abbate Aug 13, 2019 at 3:38 Are you asking how to pass (multiple) data to a template invocation? Possible duplicate Golang pass multiple values from template to template? – icza Aug 13, 2019 at 7:06 I personally maintain a number of functions and pass them to the engine as a map of functions. – Markus W Mahlberg Aug 13, 2019 at 14:39 @icza No, I'm not asking that. I know one can pass data to a template invocation in a struct defined in the calling Go code. But in Jinja2 (and Django templates, if I'm not mistaken) it's possible to call a macro (equivalent to a Go template) with constants strings (or numbers) as shown above. In Go, it appears you have to put those constants in the calling Go code, not in the template. – Joe Abbate Aug 13, 2019 at 22:50

Go templates are intentionally pretty basic. You're going to find that most of the time when you're looking for something that doesn't seem possible, you probably will end up solving it with a golang function. It helps keep templates simpler and pushes code into golang functions which are far more testable.

https://golang.org/pkg/html/template/#Template.Funcs

Alternatively, there are a number of alternative templating engines that are more full featured.

I took a quick look at pongo2 mentioned above, but decided to continue using bare Go templates (with functions of course) for now. – Joe Abbate Sep 4, 2019 at 3:21

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.