Kaydet (Commit) 8137027f authored tarafından Julien Phalip's avatar Julien Phalip

Fixed #13956 -- Enabled `*args` and `**kwargs` support for `simple_tag`,…

Fixed #13956 -- Enabled `*args` and `**kwargs` support for `simple_tag`, `inclusion_tag` and `assignment_tag`. Many thanks to Stephen Burrows for the report and initial patch, to Gregor Müllegger for the initial tests, to SamBull for the suggestions, and to Jannis Leidel for the review and PEP8 cleanup.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16908 bcc190cf-cafb-0310-a4f2-bffc1f526a37
üst 29b8e34d
This diff is collapsed.
......@@ -10,64 +10,13 @@ from django.template.base import (Node, NodeList, Template, Library,
TemplateSyntaxError, VariableDoesNotExist, InvalidTemplateLibrary,
BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END,
SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END,
get_library)
get_library, token_kwargs, kwarg_re)
from django.template.smartif import IfParser, Literal
from django.template.defaultfilters import date
from django.utils.encoding import smart_str, smart_unicode
from django.utils.safestring import mark_safe
register = Library()
# Regex for token keyword arguments
kwarg_re = re.compile(r"(?:(\w+)=)?(.+)")
def token_kwargs(bits, parser, support_legacy=False):
"""
A utility method for parsing token keyword arguments.
:param bits: A list containing remainder of the token (split by spaces)
that is to be checked for arguments. Valid arguments will be removed
from this list.
:param support_legacy: If set to true ``True``, the legacy format
``1 as foo`` will be accepted. Otherwise, only the standard ``foo=1``
format is allowed.
:returns: A dictionary of the arguments retrieved from the ``bits`` token
list.
There is no requirement for all remaining token ``bits`` to be keyword
arguments, so the dictionary will be returned as soon as an invalid
argument format is reached.
"""
if not bits:
return {}
match = kwarg_re.match(bits[0])
kwarg_format = match and match.group(1)
if not kwarg_format:
if not support_legacy:
return {}
if len(bits) < 3 or bits[1] != 'as':
return {}
kwargs = {}
while bits:
if kwarg_format:
match = kwarg_re.match(bits[0])
if not match or not match.group(1):
return kwargs
key, value = match.groups()
del bits[:1]
else:
if len(bits) < 3 or bits[1] != 'as':
return kwargs
key, value = bits[2], bits[0]
del bits[:3]
kwargs[key] = parser.compile_filter(value)
if bits and not kwarg_format:
if bits[0] != 'and':
return kwargs
del bits[:1]
return kwargs
class AutoEscapeControlNode(Node):
"""Implements the actions of the autoescape tag."""
......
......@@ -698,6 +698,29 @@ If you need to rename your tag, you can provide a custom name for it::
def some_function(value):
return value - 1
.. versionadded:: 1.4
``simple_tag`` functions may accept any number of positional or keyword
arguments. For example:
.. code-block:: python
@register.simple_tag
def my_tag(a, b, *args, **kwargs):
warning = kwargs['warning']
profile = kwargs['profile']
...
return ...
Then in the template any number of arguments, separated by spaces, may be
passed to the template tag. Like in Python, the values for keyword arguments
are set using the equal sign ("``=``") and must be provided after the positional
arguments. For example:
.. code-block:: html+django
{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}
.. _howto-custom-template-tags-assignment-tags:
Assignment tags
......@@ -761,6 +784,27 @@ Or, using decorator syntax:
For more information on how the ``takes_context`` option works, see the section
on :ref:`inclusion tags<howto-custom-template-tags-inclusion-tags>`.
``assignment_tag`` functions may accept any number of positional or keyword
arguments. For example:
.. code-block:: python
@register.assignment_tag
def my_tag(a, b, *args, **kwargs):
warning = kwargs['warning']
profile = kwargs['profile']
...
return ...
Then in the template any number of arguments, separated by spaces, may be
passed to the template tag. Like in Python, the values for keyword arguments
are set using the equal sign ("``=``") and must be provided after the positional
arguments. For example:
.. code-block:: html+django
{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile as the_result %}
.. _howto-custom-template-tags-inclusion-tags:
Inclusion tags
......@@ -884,6 +928,29 @@ The ``takes_context`` parameter defaults to ``False``. When it's set to *True*,
the tag is passed the context object, as in this example. That's the only
difference between this case and the previous ``inclusion_tag`` example.
.. versionadded:: 1.4
``inclusion_tag`` functions may accept any number of positional or keyword
arguments. For example:
.. code-block:: python
@register.inclusion_tag('my_template.html')
def my_tag(a, b, *args, **kwargs):
warning = kwargs['warning']
profile = kwargs['profile']
...
return ...
Then in the template any number of arguments, separated by spaces, may be
passed to the template tag. Like in Python, the values for keyword arguments
are set using the equal sign ("``=``") and must be provided after the positional
arguments. For example:
.. code-block:: html+django
{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}
Setting a variable in the context
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
......@@ -162,6 +162,31 @@ A new helper function,
``template.Library`` to ease the creation of template tags that store some
data in a specified context variable.
``*args`` and ``**kwargs`` support for template tag helper functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:ref:`simple_tag<howto-custom-template-tags-simple-tags>`, :ref:`inclusion_tag
<howto-custom-template-tags-inclusion-tags>` and the newly introduced
:ref:`assignment_tag<howto-custom-template-tags-assignment-tags>` template
helper functions may now accept any number of positional or keyword arguments.
For example:
.. code-block:: python
@register.simple_tag
def my_tag(a, b, *args, **kwargs):
warning = kwargs['warning']
profile = kwargs['profile']
...
return ...
Then in the template any number of arguments may be passed to the template tag.
For example:
.. code-block:: html+django
{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}
``truncatechars`` template filter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment