diff --git a/django/template/base.py b/django/template/base.py index eacc29cfcd..78da99813b 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -866,7 +866,7 @@ class Library(object): self.filters[getattr(func, "_decorated_function", func).__name__] = func return func - def simple_tag(self, func=None, takes_context=None): + def simple_tag(self, func=None, takes_context=None, name=None): def dec(func): params, xx, xxx, defaults = getargspec(func) if takes_context: @@ -887,9 +887,10 @@ class Library(object): func_args = resolved_vars return func(*func_args) - compile_func = partial(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, SimpleNode) + function_name = name or getattr(func, '_decorated_function', func).__name__ + compile_func = partial(generic_tag_compiler, params, defaults, function_name, SimpleNode) compile_func.__doc__ = func.__doc__ - self.tag(getattr(func, "_decorated_function", func).__name__, compile_func) + self.tag(function_name, compile_func) return func if func is None: @@ -901,7 +902,7 @@ class Library(object): else: raise TemplateSyntaxError("Invalid arguments provided to simple_tag") - def assignment_tag(self, func=None, takes_context=None): + def assignment_tag(self, func=None, takes_context=None, name=None): def dec(func): params, xx, xxx, defaults = getargspec(func) if takes_context: @@ -948,8 +949,9 @@ class Library(object): % (tag_name, params_min, params_max)) return AssignmentNode(params_vars, target_var) + function_name = name or getattr(func, '_decorated_function', func).__name__ compile_func.__doc__ = func.__doc__ - self.tag(getattr(func, "_decorated_function", func).__name__, compile_func) + self.tag(function_name, compile_func) return func if func is None: @@ -961,7 +963,7 @@ class Library(object): else: raise TemplateSyntaxError("Invalid arguments provided to assignment_tag") - def inclusion_tag(self, file_name, context_class=Context, takes_context=False): + def inclusion_tag(self, file_name, context_class=Context, takes_context=False, name=None): def dec(func): params, xx, xxx, defaults = getargspec(func) if takes_context: @@ -1003,9 +1005,10 @@ class Library(object): new_context['csrf_token'] = csrf_token return self.nodelist.render(new_context) - compile_func = partial(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode) + function_name = name or getattr(func, '_decorated_function', func).__name__ + compile_func = partial(generic_tag_compiler, params, defaults, function_name, InclusionNode) compile_func.__doc__ = func.__doc__ - self.tag(getattr(func, "_decorated_function", func).__name__, compile_func) + self.tag(function_name, compile_func) return func return dec diff --git a/docs/howto/custom-template-tags.txt b/docs/howto/custom-template-tags.txt index 1b56cf85c3..97f1e9a53b 100644 --- a/docs/howto/custom-template-tags.txt +++ b/docs/howto/custom-template-tags.txt @@ -687,6 +687,16 @@ Or, using decorator syntax:: For more information on how the ``takes_context`` option works, see the section on :ref:`inclusion tags`. +.. versionadded:: 1.4 + +If you need to rename your tag, you can provide a custom name for it:: + + register.simple_tags(lambda x: x - 1, name='minusone') + + @register.simple_tag(name='minustwo') + def some_function(value): + return value - 1 + .. _howto-custom-template-tags-assignment-tags: Assignment tags diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt index 0fbcd34d77..65f3dfe050 100644 --- a/docs/releases/1.4.txt +++ b/docs/releases/1.4.txt @@ -175,6 +175,7 @@ Django 1.4 also includes several smaller improvements worth noting: code are slightly emphasized. This change makes it easier to scan a stacktrace for issues in user code. +* Customizable names for :meth:`~django.template.Library.simple_tag`. .. _backwards-incompatible-changes-1.4: diff --git a/tests/regressiontests/templates/templatetags/custom.py b/tests/regressiontests/templates/templatetags/custom.py index 2e281f7b0f..97f2674953 100644 --- a/tests/regressiontests/templates/templatetags/custom.py +++ b/tests/regressiontests/templates/templatetags/custom.py @@ -114,3 +114,9 @@ def assignment_params_and_context(context, arg): """Expected assignment_params_and_context __doc__""" return "assignment_params_and_context - Expected result (context value: %s): %s" % (context['value'], arg) assignment_params_and_context.anything = "Expected assignment_params_and_context __dict__" + +register.simple_tag(lambda x: x - 1, name='minusone') + +@register.simple_tag(name='minustwo') +def minustwo_overridden_name(value): + return value - 2 diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index a56168611b..36a1ca3fe0 100644 --- a/tests/regressiontests/templates/tests.py +++ b/tests/regressiontests/templates/tests.py @@ -1385,6 +1385,11 @@ class Templates(unittest.TestCase): 'templatetag11': ('{% templatetag opencomment %}', {}, '{#'), 'templatetag12': ('{% templatetag closecomment %}', {}, '#}'), + # Simple tags with customized names + 'simpletag-renamed01': ('{% load custom %}{% minusone 7 %}', {}, '6'), + 'simpletag-renamed02': ('{% load custom %}{% minustwo 7 %}', {}, '5'), + 'simpletag-renamed03': ('{% load custom %}{% minustwo_overridden_name 7 %}', {}, template.TemplateSyntaxError), + ### WIDTHRATIO TAG ######################################################## 'widthratio01': ('{% widthratio a b 0 %}', {'a':50,'b':100}, '0'), 'widthratio02': ('{% widthratio a b 100 %}', {'a':0,'b':0}, ''),