Reputation: 4904
How are extra args & kwargs handled for a Jinja2 macro? The documentation isn't exactly clear offhand.
For example, this is clearly wrong:
{% macro example_1(one, two, **kwargs) %}
do macro stuff
{% endmacro %}
which results in
jinja2.exceptions.TemplateSyntaxError
TemplateSyntaxError: expected token 'name', got '**'
The documentation says:
kwargs
Like varargs but for keyword arguments. All unconsumed keyword arguments are stored in this special variable.
Unfortunately, any combo of extra keyword arguments is an error,
{% macro example_2(one, two) %}
do macro stuff
{% endmacro %}
{{ example_2(one, two, test='test') }}
TypeError: macro 'example_2' takes no keyword keyword argument 'test'
I have no examples and am not poking about in the Jinja2 source code atm. The documentation isn't clear to me at this point. Any thoughts appreciated.
Upvotes: 72
Views: 20993
Reputation: 1005
Just to add to Sean Viera's answer, the kwargs
object will be a dictionary so if you want to use it you can iterate over it by accessing the items()
method, like in normal Python:
{% macro iterate_kwargs() %}
{% for key, value in kwargs.items() %}
The key, {{ key }}, has a value of {{ value }}
{%- endfor -%}
{% endmacro %}
{{ iterate_kwargs(id=123, colour="blue", size="S") }}
This will output the following:
The key, id, has a value of 123
The key, colour, has a value of blue
The key, size, has a value of S
This was written and tested using dbt so may not be available to all tools that use Jinja
Upvotes: 0
Reputation: 160033
The trick is that kwargs
has to be accessed at least once in any macro that should accept them. That is to say, you must call {{ kwargs }}
once in macro body without declaring it in macro argument list. The same is true for {{ varargs }}
.
This will not work
{% macro example_2(one, two) %}
* {{one}} - {{two}}
{% endmacro %}
{{example_2(1, 2, test="Hello")}}
This will
{% macro example_2(one, two) %}
* {{one}} - {{two}}
* {{kwargs}}
{% endmacro %}
{{example_2(1, 2, test="Hello")}}
Upvotes: 89