Fixed #2320 -- corrected numerous errors in the custom tag examples in

python_templates.txt. Also fixed an argument parsing error for such tags.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@3308 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2006-07-10 10:48:08 +00:00
parent c1847294b8
commit 927d87d732
2 changed files with 23 additions and 22 deletions

View File

@ -171,7 +171,7 @@ class Token(object):
self.contents[:20].replace('\n', '')) self.contents[:20].replace('\n', ''))
def split_contents(self): def split_contents(self):
return smart_split(self.contents) return list(smart_split(self.contents))
class Lexer(object): class Lexer(object):
def __init__(self, template_string, origin): def __init__(self, template_string, origin):
@ -758,7 +758,7 @@ class DebugVariableNode(VariableNode):
def generic_tag_compiler(params, defaults, name, node_class, parser, token): def generic_tag_compiler(params, defaults, name, node_class, parser, token):
"Returns a template.Node subclass." "Returns a template.Node subclass."
bits = token.contents.split()[1:] bits = token.split_contents()[1:]
bmax = len(params) bmax = len(params)
def_len = defaults and len(defaults) or 0 def_len = defaults and len(defaults) or 0
bmin = bmax - def_len bmin = bmax - def_len

View File

@ -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 `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:: else. In our case, let's say the tag should be used like this::
<p>The time is {% current_time "%Y-%M-%d %I:%M %p" %}.</p> <p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>
.. _`strftime syntax`: http://www.python.org/doc/current/lib/module-time.html#l2h-1941 .. _`strftime syntax`: http://www.python.org/doc/current/lib/module-time.html#l2h-1941
@ -653,10 +653,10 @@ object::
from django import template from django import template
def do_current_time(parser, token): def do_current_time(parser, token):
try: try:
# Splitting by None == splitting by spaces. # split_contents() knows not to split quoted strings.
tag_name, format_string = token.contents.split(None, 1) tag_name, format_string = token.split_contents()
except ValueError: 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 ('"', "'")): 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 raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
return CurrentTimeNode(format_string[1:-1]) return CurrentTimeNode(format_string[1:-1])
@ -667,7 +667,11 @@ Notes:
example. example.
* ``token.contents`` is a string of the raw contents of the tag. In our * ``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 * This function is responsible for raising
``django.template.TemplateSyntaxError``, with helpful messages, for ``django.template.TemplateSyntaxError``, with helpful messages, for
@ -681,7 +685,7 @@ Notes:
* The function returns a ``CurrentTimeNode`` with everything the node needs * The function returns a ``CurrentTimeNode`` with everything the node needs
to know about this tag. In this case, it just passes the argument -- 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]``. template tag are removed in ``format_string[1:-1]``.
* The parsing is very low-level. The Django developers have experimented * 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:: Our earlier ``current_time`` function could thus be written like this::
# This version of do_current_time takes only a single argument and returns def current_time(format_string):
# a string. return datetime.datetime.now().strftime(format_string)
def do_current_time(token): register.simple_tag(current_time)
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)
In Python 2.4, the decorator syntax also works:: In Python 2.4, the decorator syntax also works::
@register.simple_tag @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 Inclusion tags
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~