#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: | no | UI/UX: | no |
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)
Change History (5)
by , 15 years ago
Attachment: | ifequal-template-bug.diff added |
---|
comment:1 by , 15 years ago
Needs tests: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:3 by , 15 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
comment:4 by , 15 years ago
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.
Patches defaulttags.py (ifchanged needs the same methods overridden)