Search code examples
pythondjango-templatesjinja2

jinja2: How to make it fail Silently like djangotemplate


Well i don't find the answer I'm sure that it's very simple, but i just don't find out how to make it work like Django when it doesn't find a variable

i tried to use Undefined and create my own undefined but it give me problems of attribute error etc.

def silently(*args, **kwargs):
    return u''

class UndefinedSilently(Undefined):
    __unicode__ = silently
    __str__ = silently
    __call__ = silently
    __getattr__ = silently

but when i try this here it fails TypeError: 'unicode' object is not callable:

{%for dir_name, links in menu_links.items()%}

Solution

  • You are trying to go arbitrarily deep into your undefined data. menu_links is undefined, so Jinja2 creates a new instance of your UndefinedSilently class. It then calls the __getattr__ method of this object to get the items attribute. This returns a blank unicode string. Which Python then tries to call (the () of menu_links.items()). Which raises the error that unicode objects are not callables.

    That is:

    menu_links.items() # becomes
    UndefinedSilently().items() # becomes
    UndefinedSilently().u''() # from UndefinedSilently.__getattr__
    

    If you want to be able to go deeper than one level you can create a class that returns itself for every access attempt except __str__ and __unicode__.

    def silently(*args, **kwargs):
        return u''
    
    return_new = lambda *args, **kwargs: UndefinedSilently()
    
    class UndefinedSilently(Undefined):
        __unicode__ = silently
        __str__ = silently
        __call__ = return_new
        __getattr__ = return_new