Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphic macros in Jinja

Tags:

python

jinja2

I am looking for a way to have a Jinja macro that calls different implementations depending on the type of object that is being passed. Basically, standard Python method polymorphism. Right now, I'm using an ugly workaround similar to this:

{% macro menuitem(obj) %}
  {% set type = obj.__class__.__name__ %}
  {% if type == "ImageMenuItem" %}
    {{ imagemenuitem(obj) }}
  {% elif type == "FoobarMenuItem" %}
    {{ foobarmenuitem(obj) }}
  {% else %}
    {{ textmenuitem(obj) }}
  {% endif %}
{% endmacro %}

In pure Python, one can muck around with the module environment, e.g. globals()[x+'menuitem'], which isn't pretty but works very well. I've tried something similar using the Jinja context, but the latter doesn't seem to contain the macro definitions.

What better ways are there to achieve what I'm seeking?

like image 971
Daniel Werner Avatar asked May 17 '26 10:05

Daniel Werner


1 Answers

The essence of OOP: polymorphism.

Create a presentation Layer for your objects:

class MenuPresentation:
    def present(self):
        raise NotImplementedException()

class ImageMenuPresentation(MenuPresentation):
   def present(self):
       return "magic url "

class TextMenuPresentation(MenuPresentation):
   def present(self):
      return "- text value here"

And then will be just a matter of:

{% macro menuitem(obj) %}
  {{ obj.present() }}
{% endmacro %}
like image 193
fabrizioM Avatar answered May 18 '26 23:05

fabrizioM



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!