diff --git a/django/template/__init__.py b/django/template/__init__.py index a1d1d402d0..e898fc7636 100644 --- a/django/template/__init__.py +++ b/django/template/__init__.py @@ -171,7 +171,7 @@ class Token(object): self.contents[:20].replace('\n', '')) def split_contents(self): - return smart_split(self.contents) + return list(smart_split(self.contents)) class Lexer(object): def __init__(self, template_string, origin): @@ -758,7 +758,7 @@ class DebugVariableNode(VariableNode): def generic_tag_compiler(params, defaults, name, node_class, parser, token): "Returns a template.Node subclass." - bits = token.contents.split()[1:] + bits = token.split_contents()[1:] bmax = len(params) def_len = defaults and len(defaults) or 0 bmin = bmax - def_len diff --git a/docs/templates_python.txt b/docs/templates_python.txt index 2fa837e424..894e23bd17 100644 --- a/docs/templates_python.txt +++ b/docs/templates_python.txt @@ -643,7 +643,7 @@ the current date/time, formatted according to a parameter given in the tag, in `strftime syntax`_. It's a good idea to decide the tag syntax before anything else. In our case, let's say the tag should be used like this:: -

The time is {% current_time "%Y-%M-%d %I:%M %p" %}.

+

The time is {% current_time "%Y-%m-%d %I:%M %p" %}.

.. _`strftime syntax`: http://www.python.org/doc/current/lib/module-time.html#l2h-1941 @@ -653,10 +653,10 @@ object:: from django import template def do_current_time(parser, token): try: - # Splitting by None == splitting by spaces. - tag_name, format_string = token.contents.split(None, 1) + # split_contents() knows not to split quoted strings. + tag_name, format_string = token.split_contents() except ValueError: - raise template.TemplateSyntaxError, "%r tag requires an argument" % token.contents[0] + raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents[0] if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")): raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name return CurrentTimeNode(format_string[1:-1]) @@ -667,7 +667,11 @@ Notes: example. * ``token.contents`` is a string of the raw contents of the tag. In our - example, it's ``'current_time "%Y-%M-%d %I:%M %p"'``. + example, it's ``'current_time "%Y-%m-%d %I:%M %p"'``. + + * The ``token.split_contents()`` method separates the arguments on spaces, + whilst keeping quoted strings together. The more straightforward + ``token.contents.split()`` would be as robust. * This function is responsible for raising ``django.template.TemplateSyntaxError``, with helpful messages, for @@ -681,7 +685,7 @@ Notes: * The function returns a ``CurrentTimeNode`` with everything the node needs to know about this tag. In this case, it just passes the argument -- - ``"%Y-%M-%d %I:%M %p"``. The leading and trailing quotes from the + ``"%Y-%m-%d %I:%M %p"``. The leading and trailing quotes from the template tag are removed in ``format_string[1:-1]``. * The parsing is very low-level. The Django developers have experimented @@ -766,27 +770,24 @@ registers it with the template system. Our earlier ``current_time`` function could thus be written like this:: - # This version of do_current_time takes only a single argument and returns - # a string. + def current_time(format_string): + return datetime.datetime.now().strftime(format_string) - def do_current_time(token): - try: - # Splitting by None == splitting by spaces. - tag_name, format_string = token.contents.split(None, 1) - except ValueError: - raise template.TemplateSyntaxError, "%r tag requires an argument" % token.contents[0] - if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")): - raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name - return datetime.datetime.now().strftime(self.format_string[1:-1]) - - register.simple_tag(do_current_time) + register.simple_tag(current_time) In Python 2.4, the decorator syntax also works:: @register.simple_tag - def do_current_time(token): + def current_time(token): ... +A couple of things to note about the ``simple_tag`` helper function: + * Only the (single) argument is passed into our function.i + * Checking for the required number of arguments, etc, has already been + done by the time our function is called, so we don't need to do that. + * The quotes around the argument (if any) have already been stripped away, + so we just receive a plain string. + Inclusion tags ~~~~~~~~~~~~~~