Django

Code

Ticket #7251 (new)

Opened 2 months ago

Last modified 1 month ago

Template if/ifequal/ifnotequal evaluate despite condition

Reported by: Joshua 'jag' Ginsberg <jag@fsf.org> Assigned to: nobody
Milestone: Component: Template system
Version: SVN Keywords:
Cc: Triage Stage: Unreviewed
Has patch: 1 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 0

Description

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

Attachments

django-if-tag.patch (3.3 kB) - added by Joshua 'jag' Ginsberg <jag@fsf.org> on 05/16/08 13:25:27.
django-if-tag.2.patch (2.0 kB) - added by Joshua 'jag' Ginsberg <jag@fsf.org> on 05/16/08 13:52:44.

Change History

05/16/08 13:25:27 changed by Joshua 'jag' Ginsberg <jag@fsf.org>

  • attachment django-if-tag.patch added.

05/16/08 13:52:44 changed by Joshua 'jag' Ginsberg <jag@fsf.org>

  • attachment django-if-tag.2.patch added.

06/07/08 10:02:02 changed by jshaffer

  • needs_better_patch changed.
  • needs_tests changed.
  • needs_docs changed.

Add/Change #7251 (Template if/ifequal/ifnotequal evaluate despite condition)




Change Properties
Action