*args, **kwargs in jinja2 macros

13,997

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")}}
Share:
13,997
blueblank
Author by

blueblank

Updated on July 03, 2022

Comments

  • blueblank
    blueblank almost 2 years

    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.

  • BrenBarn
    BrenBarn over 11 years
    Wow, that is a very distasteful design choice.
  • Sean Vieira
    Sean Vieira over 11 years
    @BrenBarn - I have to agree with you - there is a lot of awesome stuff in Jinja - the magical pseudo-globals are not of that category.
  • Taylor D. Edmiston
    Taylor D. Edmiston about 8 years
    I won't claim this is great, but at least we can put it in a comment to get stripped out at render time {# {{kwargs}} #}
  • Jakob Simon-Gaarde
    Jakob Simon-Gaarde almost 8 years
    The comment approach didn't work for me. Might be version specific.
  • hyperknot
    hyperknot over 7 years
    Do you mean I'm supposed to write {% if False %}{{ kwargs }}{% endif %} or the version Taylor wrote? Oh...
  • 4m1nh4j1
    4m1nh4j1 almost 7 years
    @SeanVieira What do you mean by: kwargs has to be accessed at least once ? Could you please explain more ?
  • Sean Vieira
    Sean Vieira almost 7 years
    @4m1nh4j1 - if you look at the second code snippet in my answer you'll see that I'm using kwargs - that lets me call example_2 with "extra" arguments and not have it blow up. The first code snippet does not do anything with kwargs and so blows up when I pass it extra arguments. Does that make sense?
  • Eric O.
    Eric O. over 5 years
    For those who the * {{ kwargs }} is showing in the browser view, this might be helpful: You can put * {{ kwargs }} in an element which you can then give a style of display none e.g <span class="d-none">* {{ kwargs }}</span> # for bootstrap OR <span style="display:none;">* {{ kwargs }}</span>
  • George Udosen
    George Udosen about 4 years
    This {{lwargs}}, is it acting like a **kwargs works cause I have a similar situation that involves passing in much variables to be used in the template @seanvieira?