Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#11730 closed (duplicate)

ifequal tag incorrectly renders block tag

Reported by: psmith Owned by: nobody
Component: Template system Version: 1.1
Severity: Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: UI/UX:

Description

If a child template overrides a block tag within an ifequal tag with arguments that are equal to each other, the output will be the contents of the parent's block.

The behavior should be the same as a block tag within an if tag that evaluates to "true", which works as expected.

Example:

Parent template:

<h2>This is the {% block which %}parent{% endblock %}</h2>
<p>Block output: {% block foo %}Parent!{% endblock %}</p>
<p>Go to: <a href="/">Parent</a> | <a href="/child/">Child</a></p>

Child template:

{% extends "parent.html" %}

{% block which %}child{% endblock %}

{% ifequal 1 1 %}
{% block foo %}Child!{% endblock %}
{% endifequal %}

The reason for the bug is that the IfEqualNode should override get_nodes_by_type() and __iter()__ because its node lists are in two different instance variables.

Attachments (1)

ifequal-template-bug.diff (1.5 KB) - added by psmith 6 years ago.
Patches defaulttags.py (ifchanged needs the same methods overridden)

Download all attachments as: .zip

Change History (5)

Changed 6 years ago by psmith

Patches defaulttags.py (ifchanged needs the same methods overridden)

comment:1 Changed 6 years ago by Alex

  • Needs documentation unset
  • Needs tests set
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

comment:2 Changed 6 years ago by dc

Duplicate of #10975

comment:3 Changed 6 years ago by dc

  • Resolution set to duplicate
  • Status changed from new to closed

comment:4 Changed 6 years ago by psmith

I think there are two different things going on here (considering #10975). One is a design decision about whether a block tag can be conditionally defined or overridden, within in an ifequal or if tag. I'll note that Django templates are currently inconsistent in this regard: you can define/override a block in an if tag, but not an ifequal tag.

The other is the self-evident bug in IfEqualNode (django/template/defaulttags.py), where the method get_nodes_by_type() -- as defined on the Node superclass -- will not return a list of nodes of the given nodetype, because the node list instance variable iterated over in the superclass's get_nodes_by_type() is self.nodelist, but this instance variable does not exist in IfEqualNode objects: the list of nodes are kept in two separate instance variables, self.nodelist_true and self.nodelist_false, for nodes in the initial and required "true" part of the tag, and for nodes in the optional "else" part of the tag, respectively. The patch on this ticket fixes this bug.

The two issues are related because fixing the IfEqualNode bug would enable block tags to be defined or overridden with the same behavior they have in if tags, so while a decision about whether this behavior is allowed or not in Django templates should be addressed, in the short term the fix to IfEqualNode could be applied and there would at least be consistent behavior across conditional tags.

Note: See TracTickets for help on using tickets.
Back to Top