making django templates "strict"?

201 views
Skip to first unread message

Webb S.

unread,
Jul 10, 2010, 6:36:04 PM7/10/10
to Google App Engine
Is there a way (in Linux) to make the rendering of Django templates
error out when a object property is undefined?

So that <p>blah {{ bldg.name }} </p> throws a big fat stack trace,
rather than rendering to <p> blah </p>

This is mostly a problem for me with generated javascript code which
is building a map. I am sure there is a better way for that, but I
haven't found it yet, and I would prefer to render templates strictly
anyway.

Tx!

Niklasro(.appspot)

unread,
Jul 11, 2010, 7:57:20 AM7/11/10
to Google App Engine
Answer is yes just test if (not) None or likewise just that doing with
no none and no null tests getting it farther than obvious.

Webb S.

unread,
Jul 12, 2010, 1:09:26 AM7/12/10
to Google App Engine


On Jul 11, 4:57 am, "Niklasro(.appspot)" <nikla...@gmail.com> wrote:
> Answer is yes just test if (not) None or likewise just that doing with
> no none and no null tests getting it farther than obvious.

Yeah, I realize I could add code to test for empty variables. I was
hoping for a setting that would automatically do that, like "use
strict" in Perl.

djidjadji

unread,
Jul 12, 2010, 6:25:30 AM7/12/10
to google-a...@googlegroups.com
In the django.template module:
The problem is with the FilterExpression.resolve() method.
It handles the ignore_failures case wrong.
And the VariableNode.render() should call
FilterExpression.resolve(context,True).
The default behavior is to ignore the failures.

I have found two solutions
################################
Method 1:
Write a custom template filter that calls resolve_variable, and thus
raise an exception if {{var.arg}} fails. This will not catch the case
where var is not part of the template context {{var}}

The filter function is
-----------------------------
register = webapp.template.create_template_register()

@register.filter
def resolve(value, arg):
"""resolve the lookup of arg in value, raise exception if not found"""
return resolve_variable('var.' + arg, {'var' : value})
-----------------------------

In the template use, instead of {{var.arg}}
{{var|resolve:"arg"}}

################################
Method 2:
Monkey patch the FilterExpression.resolve() method. Replace it with a
working version.
Add the following code to your request handler .py file

-----------------------------
from google.appengine.ext.webapp import template
import django.template
from django.template import resolve_variable,VariableDoesNotExist
from django.conf import settings

##class FilterExpression(object):
## from django.template
def resolve(self, context, ignore_failures=False):
try:
obj = resolve_variable(self.var, context)
except VariableDoesNotExist:
if ignore_failures:
if settings.TEMPLATE_STRING_IF_INVALID:
return settings.TEMPLATE_STRING_IF_INVALID
else:
obj = settings.TEMPLATE_STRING_IF_INVALID
else:
# simplify the stackdump
if isinstance(e.params[1],django.template.context.Context):
raise VariableDoesNotExist(e.msg,(e.params[0],"Main context"))
raise
for func, args in self.filters:
arg_vals = []
for lookup, arg in args:
if not lookup:
arg_vals.append(arg)
else:
arg_vals.append(resolve_variable(arg, context))
obj = func(obj, *arg_vals)
return obj

django.template.FilterExpression.resolve = resolve
-----------------------------
In the template: {{var.notthere}} will raise an exception, with only
"var" in the context.
And {{notthere}} will print an exception without context dump.

2010/7/11 Webb S. <webb.s...@gmail.com>:

> --
> You received this message because you are subscribed to the Google Groups "Google App Engine" group.
> To post to this group, send email to google-a...@googlegroups.com.
> To unsubscribe from this group, send email to google-appengi...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.
>
>

Reply all
Reply to author
Forward
0 new messages