I'm trying to do something like this:
{% macro obj_type_1 %}
stuff
{% endmacro %}
{% macro obj_type_2 %}
stuff
{% endmacro %}
{{ (obj|get_type)(obj) }}
In this example, get_type
is a filter that would return obj_type_1
or obj_type_2
-- ie, the name of the macro to call for obj
. I don't want to mark up obj
with configuration output because right now obj
is used in several templates as structural data, to be rendered with different markup depending on the context.
I know the syntax here is a bit tortured, but I think that's because what I want to do isn't immediately possible in Jinja templates. I'm trying to replace a big damn schwack of if/elif/else crap in some config generation code with templates, but this bit seems to be a sticking point.
Macros within Jinja2 are essentially used like functions with Python and are great for repeating configs with identical structures (think interface configurations, ASA object-groups, etc).
Jinja supports dynamic inheritance and does not distinguish between parent and child template as long as no extends tag is visited.
You can create a Jinja2 filter which gets the Macro from the current context and then evaluates the Macro. The filter is:
@contextfilter
def call_macro_by_name(context, macro_name, *args, **kwargs):
return context.vars[macro_name](*args, **kwargs)
If your application requires, you can perform string manipulation on macro_name before looking up the Macro in context.vars.
Here is a full example:
#!/usr/bin/env python
from jinja2 import Environment, contextfilter
@contextfilter
def call_macro_by_name(context, macro_name, *args, **kwargs):
return context.vars[macro_name](*args, **kwargs)
template_string = """\
{%- macro MyMacro(item) %}MyMacro({{ item }}){% endmacro -%}
{{ MyMacro('direct') }}
{{ 'MyMacro' | macro('indirect') }}
"""
env = Environment()
env.filters['macro'] = call_macro_by_name
template = env.from_string(template_string)
print(template.render())
which prints
MyMacro(direct)
MyMacro(indirect)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With