Permalink
Browse files

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

…g`, `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
  • Loading branch information...
1 parent 29b8e34 commit 8137027fd770ceb02d593605b22b8cfff1ef2e66 @jphalip jphalip committed Sep 27, 2011
@@ -10,64 +10,13 @@
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
View
@@ -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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Oops, something went wrong. Retry.

0 comments on commit 8137027

Please sign in to comment.