Ticket #1522: smart_token_splitting.diff

File smart_token_splitting.diff, 12.1 KB (added by SmileyChris, 9 years ago)
  • django/contrib/admin/templatetags/admin_modify.py

     
    200200filter_interface_script_maybe = register.simple_tag(filter_interface_script_maybe)
    201201
    202202def do_one_arg_tag(node_factory, parser,token):
    203     tokens = token.contents.split()
     203    tokens = token.split_contents()
    204204    if len(tokens) != 2:
    205205        raise template.TemplateSyntaxError("%s takes 1 argument" % tokens[0])
    206206    return node_factory(tokens[1])
  • django/contrib/admin/templatetags/adminapplist.py

     
    4949    """
    5050    {% get_admin_app_list as app_list %}
    5151    """
    52     tokens = token.contents.split()
     52    tokens = token.split_contents()
    5353    if len(tokens) < 3:
    5454        raise template.TemplateSyntaxError, "'%s' tag requires two arguments" % tokens[0]
    5555    if tokens[1] != 'as':
  • django/contrib/admin/templatetags/log.py

     
    3838        self.tag_name = tag_name
    3939
    4040    def __call__(self, parser, token):
    41         tokens = token.contents.split()
     41        tokens = token.split_contents()
    4242        if len(tokens) < 4:
    4343            raise template.TemplateSyntaxError, "'%s' statements require two arguments" % self.tag_name
    4444        if not tokens[1].isdigit():
  • django/contrib/comments/templatetags/comments.py

     
    147147        self.free = free
    148148
    149149    def __call__(self, parser, token):
    150         tokens = token.contents.split()
     150        tokens = token.split_contents()
    151151        if len(tokens) < 4:
    152152            raise template.TemplateSyntaxError, "%r tag requires at least 3 arguments" % tokens[0]
    153153        if tokens[1] != 'for':
     
    225225        self.free = free
    226226
    227227    def __call__(self, parser, token):
    228         tokens = token.contents.split()
     228        tokens = token.split_contents()
    229229        # Now tokens is a list like this:
    230230        # ['get_comment_list', 'for', 'lcom.eventtimes', 'event.id', 'as', 'comment_list']
    231231        if len(tokens) != 6:
     
    280280        self.free = free
    281281
    282282    def __call__(self, parser, token):
    283         tokens = token.contents.split()
     283        tokens = token.split_contents()
    284284        # Now tokens is a list like this:
    285285        # ['get_comment_list', 'for', 'lcom.eventtimes', 'event.id', 'as', 'comment_list']
    286286        if not len(tokens) in (6, 7):
  • django/core/template/__init__.py

     
    8484tag_re = re.compile('(%s.*?%s|%s.*?%s)' % (re.escape(BLOCK_TAG_START), re.escape(BLOCK_TAG_END),
    8585                                          re.escape(VARIABLE_TAG_START), re.escape(VARIABLE_TAG_END)))
    8686
     87# split a token up seperating by spaces (allowing for quoted bits)
     88split_token_re = re.compile(r'(?:\'[^\']+\'|"[^"]+"|[^ ]+)(?= )*')
     89check_for_quotes = re.compile(r'[\'"]')
     90
    8791# global dictionary of libraries that have been loaded using get_library
    8892libraries = {}
    8993# global list of libraries to load by default for a new parser
     
    220224            self.contents[:].replace('\n', '')
    221225            )
    222226
     227    def split_contents(self):
     228        if check_for_quotes.search(self.contents):
     229            return split_token_re.findall(self.contents)
     230        else:
     231            return self.contents.split()
     232
     233
    223234class Lexer(object):
    224235    def __init__(self, template_string, origin):
    225236        self.template_string = template_string
     
    291302                    self.prepend_token(token)
    292303                    return nodelist
    293304                try:
    294                     command = token.contents.split()[0]
     305                    command = token.split_contents()[0]
    295306                except IndexError:
    296307                    self.empty_block_tag(token)
    297308                # execute callback function for this tag and append resulting node
     
    784795
    785796def generic_tag_compiler(params, defaults, name, node_class, parser, token):
    786797    "Returns a template.Node subclass."
    787     bits = token.contents.split()[1:]
     798    bits = token.split_contents()[1:]
    788799    bmax = len(params)
    789800    def_len = defaults and len(defaults) or 0
    790801    bmin = bmax - def_len
  • django/core/template/defaulttags.py

     
    328328    # a global variable, which would make cycle names have to be unique across
    329329    # *all* templates.
    330330
    331     args = token.contents.split()
     331    args = token.split_contents()
    332332    if len(args) < 2:
    333333        raise TemplateSyntaxError("'Cycle' statement requires at least two arguments")
    334334
     
    410410
    411411    but obviously much cleaner!
    412412    """
    413     bits = token.contents.split()[1:]
     413    bits = token.split_contents()[1:]
    414414    if len(bits) < 1:
    415415        raise TemplateSyntaxError, "'firstof' statement requires at least one argument"
    416416    return FirstOfNode(bits)
     
    450450        ==========================  ================================================
    451451
    452452    """
    453     bits = token.contents.split()
     453    bits = token.split_contents()
    454454    if len(bits) == 5 and bits[4] != 'reversed':
    455455        raise TemplateSyntaxError, "'for' statements with five words should end in 'reversed': %s" % token.contents
    456456    if len(bits) not in (4, 5):
     
    481481            ...
    482482        {% endifnotequal %}
    483483    """
    484     bits = token.contents.split()
     484    bits = token.split_contents()
    485485    if len(bits) != 3:
    486486        raise TemplateSyntaxError, "%r takes two arguments" % bits[0]
    487487    end_tag = 'end' + bits[0]
     
    550550            {% endif %}
    551551        {% endif %}
    552552    """
    553     bits = token.contents.split()
     553    bits = token.split_contents()
    554554    del bits[0]
    555555    if not bits:
    556556        raise TemplateSyntaxError, "'if' statement requires at least one argument"
     
    591591        <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
    592592        {% endfor %}
    593593    """
    594     bits = token.contents.split()
     594    bits = token.split_contents()
    595595    if len(bits) != 1:
    596596        raise TemplateSyntaxError, "'ifchanged' tag takes no arguments"
    597597    nodelist = parser.parse(('endifchanged',))
     
    615615
    616616        {% ssi /home/html/ljworld.com/includes/right_generic.html parsed %}
    617617    """
    618     bits = token.contents.split()
     618    bits = token.split_contents()
    619619    parsed = False
    620620    if len(bits) not in (2, 3):
    621621        raise TemplateSyntaxError, "'ssi' tag takes one argument: the path to the file to be included"
     
    636636
    637637        {% load news.photos %}
    638638    """
    639     bits = token.contents.split()
     639    bits = token.split_contents()
    640640    for taglib in bits[1:]:
    641641        # add the library to the parser
    642642        try:
     
    779779        ``closevariable``   ``}}``
    780780        ==================  =======
    781781    """
    782     bits = token.contents.split()
     782    bits = token.split_contents()
    783783    if len(bits) != 2:
    784784        raise TemplateSyntaxError, "'templatetag' statement takes one argument"
    785785    tag = bits[1]
     
    803803    the above example will be 88 pixels wide (because 175/200 = .875; .875 *
    804804    100 = 87.5 which is rounded up to 88).
    805805    """
    806     bits = token.contents.split()
     806    bits = token.split_contents()
    807807    if len(bits) != 4:
    808808        raise TemplateSyntaxError("widthratio takes three arguments")
    809809    tag, this_value_expr, max_value_expr, max_width = bits
  • django/core/template/loader_tags.py

     
    112112    """
    113113    Define a block that can be overridden by child templates.
    114114    """
    115     bits = token.contents.split()
     115    bits = token.split_contents()
    116116    if len(bits) != 2:
    117117        raise TemplateSyntaxError, "'%s' tag takes only one argument" % bits[0]
    118118    block_name = bits[1]
     
    137137    or ``{% extends variable %}`` uses the value of ``variable`` as the name
    138138    of the parent template to extend.
    139139    """
    140     bits = token.contents.split()
     140    bits = token.split_contents()
    141141    if len(bits) != 2:
    142142        raise TemplateSyntaxError, "'%s' takes one argument" % bits[0]
    143143    parent_name, parent_name_expr = None, None
     
    158158
    159159        {% include "foo/some_include" %}
    160160    """
    161     bits = token.contents.split()
     161    bits = token.split_contents()
    162162    if len(bits) != 2:
    163163        raise TemplateSyntaxError, "%r tag takes one argument: the name of the template to be included" % bits[0]
    164164    path = bits[1]
  • django/templatetags/i18n.py

     
    8383    your setting file (or the default settings) and
    8484    put it into the named variable.
    8585    """
    86     args = token.contents.split()
     86    args = token.split_contents()
    8787    if len(args) != 3 or args[1] != 'as':
    8888        raise TemplateSyntaxError, "'get_available_languages' requires 'as variable' (got %r)" % args
    8989    return GetAvailableLanguagesNode(args[2])
     
    100100    put it's value into the ``language`` context
    101101    variable.
    102102    """
    103     args = token.contents.split()
     103    args = token.split_contents()
    104104    if len(args) != 3 or args[1] != 'as':
    105105        raise TemplateSyntaxError, "'get_available_languages' requires 'as variable' (got %r)" % args
    106106    return GetCurrentLanguageNode(args[2])
  • tests/othertests/templates.py

     
    88from django.utils.translation import activate, deactivate, install
    99import traceback
    1010
    11 #################################
    12 # Custom template tag for tests #
    13 #################################
     11##################################
     12# Custom template tags for tests #
     13##################################
    1414
    1515register = template.Library()
    1616
     
    2222        return " ".join(self.contents)
    2323
    2424def do_echo(parser, token):
    25     return EchoNode(token.contents.split()[1:])
     25    return EchoNode(token.split_contents()[1:])
    2626
    2727register.tag("echo", do_echo)
    2828
     29
     30class TokenBitsNode(template.Node):
     31    def __init__(self, token):
     32        self.token = token
     33
     34    def render(self, context):
     35        bits = self.token.split_contents()[1:]
     36        return str(bits)
     37
     38def do_token_bits(parser, token):
     39    return TokenBitsNode(token)
     40
     41register.tag("tokenbits", do_token_bits)
     42
     43
    2944template.libraries['django.templatetags.testtags'] = register
    3045
    3146#####################################
     
    134149
    135150    # Default argument testing
    136151    'basic-syntax32' : (r'{{ var|yesno:"yup,nup,mup" }} {{ var|yesno }}', {"var": True}, 'yup yes'),
     152   
     153    # Smart token content splitting
     154    'basic-syntax33': (r'{% load testtags %}{% tokenbits one two three %}', {}, "['one', 'two', 'three']"),
     155    'basic-syntax34': (r'{% load testtags %}{% tokenbits one "two three" %}', {}, "['one', '\"two three\"']"),
     156    'basic-syntax35': (r"{% load testtags %}{% tokenbits 'one two' three %}", {}, "[\"'one two'\", 'three']"),
    137157
    138158    ### IF TAG ################################################################
    139159    'if-tag01': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": True}, "yes"),
Back to Top