The problem:
Django evaluates all branches of an if/else/endif regardless of the condition. Most of the time, given the forgiving nature of templates, this is fine. However sometimes this is really bad.
root@agilus:/srv/django/satchmo# ./manage.py shell
Python 2.5.1 (r251:54863, Mar 7 2008, 03:19:34)
[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from satchmo.shop.templatetags import satchmo_util
>>> satchmo_util.app_enabled("recentlist")
''
>>> from django.template import Template, RequestContext
>>> t = Template("""{% load satchmo_util %}{% if "recentlist"|app_enabled %}Enabled{% endif %}""")
>>> from django.template import Context
>>> ctx = Context({})
>>> t.render(ctx)
u''
>>> t = Template("""{% load satchmo_util %}{% if "recentlist"|app_enabled %}{% load satchmo_recentlist %}{% endif %}""")
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.5/site-packages/django/template/__init__.py", line 166, in __init__
self.nodelist = compile_string(template_string, origin)
File "/usr/local/lib/python2.5/site-packages/django/template/__init__.py", line 187, in compile_string
return parser.parse()
File "/usr/local/lib/python2.5/site-packages/django/template/__init__.py", line 271, in parse
compiled_result = compile_func(self, token)
File "/usr/local/lib/python2.5/site-packages/django/template/defaulttags.py", line 764, in do_if
nodelist_true = parser.parse(('else', 'endif'))
File "/usr/local/lib/python2.5/site-packages/django/template/__init__.py", line 271, in parse
compiled_result = compile_func(self, token)
File "/usr/local/lib/python2.5/site-packages/django/template/defaulttags.py", line 857, in load
(taglib, e))
TemplateSyntaxError: 'satchmo_recentlist' is not a valid tag library: Could not load template library from django.templatetags.satchmo_recentlist, No module named satchmo_recentlist
Django shouldn't have even evaluated the {% load satchmo_recentlist %} because the condition clearly fails. The same bug exists for ifequals and ifnotequals.
With the attached patch applied, we see the following behavior, which I believe is correct:
root@agilus:/srv/django/satchmo# ./manage.py shell
Python 2.5.1 (r251:54863, Mar 7 2008, 03:19:34)
[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from satchmo.shop.templatetags import satchmo_util
>>> satchmo_util.app_enabled("recentlist")
''
>>> from django.template import Template, Context
>>> t = Template("""{% load satchmo_util %}{% if "recentlist"|app_enabled %}Enabled{% endif %}""")
>>> ctx = Context({})
>>> t.render(ctx)
u''
>>> t = Template("""{% load satchmo_util %}{% if "recentlist"|app_enabled %}{% load satchmo_recentlist %}{% endif %}""")
>>> t.render(ctx)
u''
>>> t = Template("""{% load satchmo_util %}{% if "recentlist"|app_enabled %}{% load satchmo_recentlist %}{% else %}{% load nonexistant_tags %}{% endif %}""")
>>> t.render(ctx)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.5/site-packages/django/template/__init__.py", line 176, in render
return self.nodelist.render(context)
File "/usr/local/lib/python2.5/site-packages/django/template/__init__.py", line 751, in render
bits.append(self.render_node(node, context))
File "/usr/local/lib/python2.5/site-packages/django/template/debug.py", line 71, in render_node
result = node.render(context)
File "/usr/local/lib/python2.5/site-packages/django/template/defaulttags.py", line 251, in render
raise self.nodelist_false
TemplateSyntaxError: 'nonexistant_tags' is not a valid tag library: Could not load template library from django.templatetags.nonexistant_tags, No module named nonexistant_tags
>>> t = Template("""{% load satchmo_util %}{% if not "recentlist"|app_enabled %}{% load satchmo_recentlist %}{% endif %}""")
>>> t.render(ctx)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.5/site-packages/django/template/__init__.py", line 176, in render
return self.nodelist.render(context)
File "/usr/local/lib/python2.5/site-packages/django/template/__init__.py", line 751, in render
bits.append(self.render_node(node, context))
File "/usr/local/lib/python2.5/site-packages/django/template/debug.py", line 71, in render_node
result = node.render(context)
File "/usr/local/lib/python2.5/site-packages/django/template/defaulttags.py", line 246, in render
raise self.nodelist_true
TemplateSyntaxError: 'satchmo_recentlist' is not a valid tag library: Could not load template library from django.templatetags.satchmo_recentlist, No module named satchmo_recentlist
>>> t = Template("""{% load satchmo_util %}{% if "recentlist"|app_enabled %}{% load satchmo_recentlist %}{% else %}Disabled{% endif %}""")
>>> t.render(ctx)
u'Disabled'
>>> t = Template("""{% load satchmo_util %}{% ifequal 3 4 %}{% load satchmo_recentlist %}{% else %}Disabled{% endifequal %}""")
>>> t.render(ctx)
Thanks!
-jag