Question

In django, we can do this:

views.py : 

    def A(request):
        context = {test : 'test'}
        return render_to_response('index.html', context , context_instance = RequestContext(request))

    def B(request):
        context = {}
        return render_to_response('index.html', context , context_instance = RequestContext(request))

index.html:

        {% if test %}
            {{ test }}
        {% endif %}

And have our template render without error, even if i use method B, where variable 'test' does not exist, but I still can put it in the template.

I want to do the same with pylons + mako, in controller :

foo.py

    def A(self):
        c.test = 'test'
        return render('index.html')

    def B(self):
        return render('index.html')

index.html :

        % if c.test:
            ${'c.test'}
        % endif

In Django, I can do that, but in Pylons, I get an error, is there anyway to check wheter 'c.test' exists or not?

the error : AttributeError: 'ContextObj' object has no attribute 'test'

Was it helpful?

Solution

From the mako Docs on Context Variables:

% if someval is UNDEFINED:
    someval is: no value
% else:
    someval is: ${someval}
% endif

The docs describe this as referencing variable names not in the current context. Mako will set these variables to the value UNDEFINED.

I check for variables like so:

% if not someval is UNDEFINED:
    (safe to use someval)

However, if pylons/pyramid has strict_undefined=True setting, attempts to use the undefined variable results in a NameError being raised. They give a brief philisophical justification for doing it this way, instead of simply replacing un-set variables with empty strings which seems consistent with Python philosophy. Took me a while to find this, but reading that entire section on the Mako Runtime will clear up how Mako recieves, sets, and uses context variables.

Edit:
For completions sake, the documents explain the strict_undefined setting here. You can change this variable by setting it in one of your .ini files:

[app:main]
...
mako.strict_undefined = false

OTHER TIPS

I had a similar issue where I had multiple views using the same template and needed to test if a variable was set. I looked at the docs chris referenced and found another way to solve this problem regardless of how mako.strict_undefined is set. Essentially you call the get() method on the context object. In your example you could do the following:

% if context.get('test', UNDEFINED) is not UNDEFINED:
  ${test}
% endif

or

${context.get('test', '')}

That will print the same as ${test} if it exists, and print an empty string if it doesn't.

Unfortunately you can't seem to use an in operator on context which would be the most intuitive.

a bit late, so whenever you use a variable on your template that doesn't exist on your controller, pylons will raise an error, to disable the error, just put this in your environment.py :

config['pylons.strict_tmpl_context'] = False
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top