Ticket #9173: ticket9173.diff

File ticket9173.diff, 5.8 KB (added by Andy Durdin, 13 years ago)

Patch against current trunk

  • tests/regressiontests/templates/tests.py

     
    963963
    964964            'ifchanged-else04': ('{% for id in ids %}{% ifchanged %}***{{ id }}*{% else %}...{% endifchanged %}{{ forloop.counter }}{% endfor %}', {'ids': [1,1,2,2,2,3,4]}, '***1*1...2***2*3...4...5***3*6***4*7'),
    965965
     966            ### IFNOTEMPTY TAG #########################################################
     967            'ifnotempty01': ('{% ifnotempty %}hello{% endifnotempty %}', {}, ''),
     968            'ifnotempty02': ('{% ifnotempty %}pre {{ var }} post{% endifnotempty %}', {'var': ''}, ''),
     969            'ifnotempty03': ('{% ifnotempty %}pre {{ var }} post{% endifnotempty %}', {'var': 'abc'}, 'pre abc post'),
     970            'ifnotempty04': ('{% ifnotempty %}pre {% for n in nums %}{{ n }},{% endfor %} post{% endifnotempty %}', {'nums': ()}, ''),
     971            'ifnotempty05': ('{% ifnotempty %}pre {% for n in nums %}{{ n }},{% endfor %} post{% endifnotempty %}', {'nums': (1,2,3)}, 'pre 1,2,3, post'),
     972
     973            # Test the behaviour when enclosing a block
     974            'ifnotempty-inheritance01': ("{% ifnotempty %}pre {% block replaceme %}{% endblock %} post{% endifnotempty %}", {}, ''),
     975            'ifnotempty-inheritance02': ("{% extends 'ifnotempty-inheritance01' %}{% block replaceme %}mid{% endblock %}", {}, 'pre mid post'),
     976           
     977            # # Test the else clause of ifnotempty.
     978            'ifnotempty-else01': ('{% ifnotempty %}pre {{ var }} post{% else %}other{% endifnotempty %}', {'var': ''}, 'other'),
     979            'ifnotempty-else02': ('{% ifnotempty %}pre {{ var }} post{% else %}other{% endifnotempty %}', {'var': 'abc'}, 'pre abc post'),
     980
    966981            ### IFEQUAL TAG ###########################################################
    967982            'ifequal01': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 2}, ""),
    968983            'ifequal02': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 1}, "yes"),
  • django/template/defaulttags.py

     
    55from datetime import datetime
    66from itertools import groupby, cycle as itertools_cycle
    77
    8 from django.template.base import Node, NodeList, Template, Context, Variable
     8from django.template.base import Node, NodeList, Template, TextNode, Context, Variable
    99from django.template.base import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END
    1010from django.template.base import get_library, Library, InvalidTemplateLibrary
    1111from django.template.smartif import IfParser, Literal
    1212from django.template.defaultfilters import date
    1313from django.conf import settings
    14 from django.utils.encoding import smart_str, smart_unicode
     14from django.utils.encoding import force_unicode, smart_str, smart_unicode
    1515from django.utils.safestring import mark_safe
    1616
    1717register = Library()
     
    269269            return self.nodelist_false.render(context)
    270270        return ''
    271271
     272class IfNotEmptyNodeList(NodeList):
     273    def render_conditionally(self, context):
     274        any_node_rendered = False
     275        bits = []
     276        for node in self:
     277            if isinstance(node, TextNode):
     278                bits.append(self.render_node(node, context))
     279            elif isinstance(node, Node):
     280                bit = self.render_node(node, context)
     281                if bit:
     282                    any_node_rendered = True
     283                bits.append(bit)
     284            else:
     285                bits.append(node)
     286        return mark_safe(''.join([force_unicode(b) for b in bits])), any_node_rendered
     287
     288class IfNotEmptyNode(Node):
     289    child_nodelists = ('nodelist_empty', 'nodelist_not_empty')
     290
     291    def __init__(self, nodelist_empty, nodelist_not_empty):
     292        self.nodelist_empty = nodelist_empty
     293        self.nodelist_not_empty = IfNotEmptyNodeList(nodelist_not_empty)
     294
     295    def render(self, context):
     296        content, any_node_rendered = self.nodelist_not_empty.render_conditionally(context)
     297        if any_node_rendered:
     298            return content
     299        if self.nodelist_empty:
     300            return self.nodelist_empty.render(context)
     301        return ''
     302
    272303class IfEqualNode(Node):
    273304    child_nodelists = ('nodelist_true', 'nodelist_false')
    274305
     
    960991    return IfChangedNode(nodelist_true, nodelist_false, *values)
    961992
    962993@register.tag
     994def ifnotempty(parser, token):
     995    """
     996    Renders only if at least one variable or template tag within also renders.
     997
     998    This allows a variable or template tag to be surrounded by markup, with
     999    the markup omitted if the variable or template tag does not render.
     1000
     1001    An `{% else %}` block may also be used.
     1002
     1003    In the following example, the section will not be rendered unless another
     1004    template extends this one and overrides the `more_information` block::
     1005
     1006        {% ifnotempty %}
     1007            <section>
     1008                <h1>More information</h1>
     1009                {% block more_information %}{% endblock %}
     1010            </section>
     1011        {% endifnotempty %}
     1012
     1013    """
     1014    bits = token.contents.split()
     1015    if len(bits) != 1:
     1016        raise TemplateSyntaxError("ifnotempty takes no arguments")
     1017    nodelist_not_empty = parser.parse(('else', 'endifnotempty'))
     1018    token = parser.next_token()
     1019    if token.contents == 'else':
     1020        nodelist_empty = parser.parse(('endifnotempty',))
     1021        parser.delete_first_token()
     1022    else:
     1023        nodelist_empty = NodeList()
     1024    return IfNotEmptyNode(nodelist_empty, nodelist_not_empty)
     1025
     1026@register.tag
    9631027def ssi(parser, token):
    9641028    """
    9651029    Outputs the contents of a given file into the page.
Back to Top