Ticket #13956: 13956r16423.diff
File 13956r16423.diff, 25.9 KB (added by , 13 years ago) |
---|
-
django/template/base.py
diff --git a/django/template/base.py b/django/template/base.py index b96e446..8713f48 100644
a b class VariableNode(Node): 799 799 return '' 800 800 return _render_value_in_context(output, context) 801 801 802 def generic_tag_compiler(params, defaults, name, node_class, parser, token): 803 "Returns a template.Node subclass." 804 bits = token.split_contents()[1:] 802 def generic_tag_syntax_check(bits, params, defaults, name, varargs): 805 803 bmax = len(params) 806 804 def_len = defaults and len(defaults) or 0 807 805 bmin = bmax - def_len 808 if(len(bits) < bmin or len(bits) > bmax): 809 if bmin == bmax: 810 message = "%s takes %s arguments" % (name, bmin) 811 else: 812 message = "%s takes between %s and %s arguments" % (name, bmin, bmax) 813 raise TemplateSyntaxError(message) 806 if varargs is None: 807 if(len(bits) < bmin or len(bits) > bmax): 808 if bmin == bmax: 809 message = "'%s' tag takes %s argument(s)" % (name, bmin) 810 else: 811 message = "'%s' tag takes between %s and %s arguments" % (name, bmin, bmax) 812 raise TemplateSyntaxError(message) 813 else: 814 if(len(bits) < bmin): 815 message = "'%s' tag takes at least %s argument(s)" % (name, bmin) 816 raise TemplateSyntaxError(message) 817 818 def generic_tag_compiler(parser, token, params, defaults, name, node_class, varargs=None): 819 "Returns a template.Node subclass." 820 bits = token.split_contents()[1:] 821 generic_tag_syntax_check(bits, params, defaults, name, varargs) 814 822 return node_class(bits) 815 823 816 824 class Library(object): … … class Library(object): 868 876 869 877 def simple_tag(self, func=None, takes_context=None, name=None): 870 878 def dec(func): 871 params, xx, xxx, defaults = getargspec(func)879 params, varargs, xxx, defaults = getargspec(func) 872 880 if takes_context: 873 881 if params[0] == 'context': 874 882 params = params[1:] … … class Library(object): 888 896 return func(*func_args) 889 897 890 898 function_name = name or getattr(func, '_decorated_function', func).__name__ 891 compile_func = partial(generic_tag_compiler, params , defaults, function_name, SimpleNode)899 compile_func = partial(generic_tag_compiler, params=params, defaults=defaults, name=function_name, node_class=SimpleNode, varargs=varargs) 892 900 compile_func.__doc__ = func.__doc__ 893 901 self.tag(function_name, compile_func) 894 902 return func … … class Library(object): 904 912 905 913 def assignment_tag(self, func=None, takes_context=None, name=None): 906 914 def dec(func): 907 params, xx, xxx, defaults = getargspec(func)915 params, varargs, xxx, defaults = getargspec(func) 908 916 if takes_context: 909 917 if params[0] == 'context': 910 918 params = params[1:] … … class Library(object): 925 933 context[self.target_var] = func(*func_args) 926 934 return '' 927 935 936 function_name = name or getattr(func, '_decorated_function', func).__name__ 937 928 938 def compile_func(parser, token): 929 bits = token.split_contents() 930 tag_name = bits[0] 931 bits = bits[1:] 932 params_max = len(params) 933 defaults_length = defaults and len(defaults) or 0 934 params_min = params_max - defaults_length 939 bits = token.split_contents()[1:] 935 940 if (len(bits) < 2 or bits[-2] != 'as'): 936 941 raise TemplateSyntaxError( 937 942 "'%s' tag takes at least 2 arguments and the " 938 "second last argument must be 'as'" % tag_name) 939 params_vars = bits[:-2] 943 "second last argument must be 'as'" % function_name) 940 944 target_var = bits[-1] 941 if (len(params_vars) < params_min or 942 len(params_vars) > params_max): 943 if params_min == params_max: 944 raise TemplateSyntaxError( 945 "%s takes %s arguments" % (tag_name, params_min)) 946 else: 947 raise TemplateSyntaxError( 948 "%s takes between %s and %s arguments" 949 % (tag_name, params_min, params_max)) 950 return AssignmentNode(params_vars, target_var) 945 args = bits[:-2] 946 generic_tag_syntax_check(args, params, defaults, function_name, varargs) 947 return AssignmentNode(args, target_var) 951 948 952 function_name = name or getattr(func, '_decorated_function', func).__name__953 949 compile_func.__doc__ = func.__doc__ 954 950 self.tag(function_name, compile_func) 955 951 return func … … class Library(object): 965 961 966 962 def inclusion_tag(self, file_name, context_class=Context, takes_context=False, name=None): 967 963 def dec(func): 968 params, xx, xxx, defaults = getargspec(func)964 params, varargs, xxx, defaults = getargspec(func) 969 965 if takes_context: 970 966 if params[0] == 'context': 971 967 params = params[1:] … … class Library(object): 1008 1004 return self.nodelist.render(new_context) 1009 1005 1010 1006 function_name = name or getattr(func, '_decorated_function', func).__name__ 1011 compile_func = partial(generic_tag_compiler, params , defaults, function_name, InclusionNode)1007 compile_func = partial(generic_tag_compiler, params=params, defaults=defaults, name=function_name, node_class=InclusionNode, varargs=varargs) 1012 1008 compile_func.__doc__ = func.__doc__ 1013 1009 self.tag(function_name, compile_func) 1014 1010 return func -
docs/howto/custom-template-tags.txt
diff --git a/docs/howto/custom-template-tags.txt b/docs/howto/custom-template-tags.txt index 1e22684..c970022 100644
a b If you need to rename your tag, you can provide a custom name for it:: 697 697 def some_function(value): 698 698 return value - 1 699 699 700 .. versionadded:: 1.4 701 702 Simple tags can also take variable arguments. For example:: 703 704 @register.simple_tag 705 def comma_separated(*args): 706 return ', '.join([unicode(arg) for arg in args]) 707 700 708 .. _howto-custom-template-tags-assignment-tags: 701 709 702 710 Assignment tags … … The ``takes_context`` parameter defaults to ``False``. When it's set to *True*, 883 891 the tag is passed the context object, as in this example. That's the only 884 892 difference between this case and the previous ``inclusion_tag`` example. 885 893 894 .. versionadded:: 1.4 895 896 Like :ref:`simple tags <howto-custom-template-tags-simple-tags>` and 897 :ref:`assignment tags <howto-custom-template-tags-assignment-tags>`, inclusion 898 tags can accept a variable number of arguments. 899 886 900 Setting a variable in the context 887 901 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 888 902 -
docs/releases/1.4.txt
diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt index 7cc3fb1..1e50a70 100644
a b Django 1.4 also includes several smaller improvements worth noting: 189 189 190 190 * Customizable names for :meth:`~django.template.Library.simple_tag`. 191 191 192 * Variable ``*args`` support for 193 :meth:`~django.template.Library.simple_tag` and 194 :meth:`~django.template.Library.inclusion_tag`. 195 192 196 * In the documentation, a helpful :doc:`security overview </topics/security>` 193 197 page. 194 198 -
tests/regressiontests/templates/custom.py
diff --git a/tests/regressiontests/templates/custom.py b/tests/regressiontests/templates/custom.py index 74c39ab..c33eb4f 100644
a b class CustomTagTests(TestCase): 37 37 t = template.Template('{% load custom %}{% params_and_context 37 %}') 38 38 self.assertEqual(t.render(c), u'params_and_context - Expected result (context value: 42): 37') 39 39 40 t = template.Template('{% load custom %}{% simple_two_params 37 42 %}') 41 self.assertEqual(t.render(c), u'simple_two_params - Expected result: 37, 42') 42 43 t = template.Template('{% load custom %}{% simple_one_default 37 %}') 44 self.assertEqual(t.render(c), u'simple_one_default - Expected result: 37, hi') 45 46 t = template.Template('{% load custom %}{% simple_one_default 37 42 %}') 47 self.assertEqual(t.render(c), u'simple_one_default - Expected result: 37, 42') 48 49 t = template.Template('{% load custom %}{% simple_unlimited_params 37 %}') 50 self.assertEqual(t.render(c), u'simple_unlimited_params - Expected result: 37, hi') 51 52 t = template.Template('{% load custom %}{% simple_unlimited_params 37 42 56 89 %}') 53 self.assertEqual(t.render(c), u'simple_unlimited_params - Expected result: 37, 42, 56, 89') 54 55 t = template.Template('{% load custom %}{% simple_only_unlimited_params %}') 56 self.assertEqual(t.render(c), u'simple_only_unlimited_params - Expected result: ') 57 58 t = template.Template('{% load custom %}{% simple_only_unlimited_params 37 42 56 89 %}') 59 self.assertEqual(t.render(c), u'simple_only_unlimited_params - Expected result: 37, 42, 56, 89') 60 40 61 def test_simple_tag_registration(self): 41 62 # Test that the decorators preserve the decorated function's docstring, name and attributes. 42 63 self.verify_tag(custom.no_params, 'no_params') … … class CustomTagTests(TestCase): 73 94 t = template.Template('{% load custom %}{% inclusion_params_and_context 37 %}') 74 95 self.assertEqual(t.render(c), u'inclusion_params_and_context - Expected result (context value: 42): 37\n') 75 96 97 t = template.Template('{% load custom %}{% inclusion_two_params 37 42 %}') 98 self.assertEqual(t.render(c), u'inclusion_two_params - Expected result: 37, 42\n') 99 100 t = template.Template('{% load custom %}{% inclusion_one_default 37 %}') 101 self.assertEqual(t.render(c), u'inclusion_one_default - Expected result: 37, hi\n') 102 103 t = template.Template('{% load custom %}{% inclusion_one_default 37 42 %}') 104 self.assertEqual(t.render(c), u'inclusion_one_default - Expected result: 37, 42\n') 105 106 t = template.Template('{% load custom %}{% inclusion_unlimited_params 37 %}') 107 self.assertEqual(t.render(c), u'inclusion_unlimited_params - Expected result: 37, hi\n') 108 109 t = template.Template('{% load custom %}{% inclusion_unlimited_params 37 42 56 89 %}') 110 self.assertEqual(t.render(c), u'inclusion_unlimited_params - Expected result: 37, 42, 56, 89\n') 111 112 t = template.Template('{% load custom %}{% inclusion_only_unlimited_params %}') 113 self.assertEqual(t.render(c), u'inclusion_only_unlimited_params - Expected result: \n') 114 115 t = template.Template('{% load custom %}{% inclusion_only_unlimited_params 37 42 56 89 %}') 116 self.assertEqual(t.render(c), u'inclusion_only_unlimited_params - Expected result: 37, 42, 56, 89\n') 117 118 self.assertRaisesRegexp(template.TemplateSyntaxError, 119 "'inclusion_two_params' tag takes 2 argument\(s\)", 120 template.Template, '{% load custom %}{% inclusion_two_params 37 42 56 %}') 121 122 self.assertRaisesRegexp(template.TemplateSyntaxError, 123 "'inclusion_one_default' tag takes between 1 and 2 arguments", 124 template.Template, '{% load custom %}{% inclusion_one_default 37 42 56 %}') 125 126 self.assertRaisesRegexp(template.TemplateSyntaxError, 127 "'inclusion_one_default' tag takes between 1 and 2 arguments", 128 template.Template, '{% load custom %}{% inclusion_one_default %}') 129 130 self.assertRaisesRegexp(template.TemplateSyntaxError, 131 "'inclusion_unlimited_params' tag takes at least 1 argument\(s\)", 132 template.Template, '{% load custom %}{% inclusion_unlimited_params %}') 133 76 134 def test_inclusion_tags_from_template(self): 77 135 c = template.Context({'value': 42}) 78 136 … … class CustomTagTests(TestCase): 91 149 t = template.Template('{% load custom %}{% inclusion_params_and_context_from_template 37 %}') 92 150 self.assertEqual(t.render(c), u'inclusion_params_and_context_from_template - Expected result (context value: 42): 37\n') 93 151 152 t = template.Template('{% load custom %}{% inclusion_two_params_from_template 37 42 %}') 153 self.assertEqual(t.render(c), u'inclusion_two_params_from_template - Expected result: 37, 42\n') 154 155 t = template.Template('{% load custom %}{% inclusion_one_default_from_template 37 %}') 156 self.assertEqual(t.render(c), u'inclusion_one_default_from_template - Expected result: 37, hi\n') 157 158 t = template.Template('{% load custom %}{% inclusion_one_default_from_template 37 42 %}') 159 self.assertEqual(t.render(c), u'inclusion_one_default_from_template - Expected result: 37, 42\n') 160 161 t = template.Template('{% load custom %}{% inclusion_unlimited_params_from_template 37 %}') 162 self.assertEqual(t.render(c), u'inclusion_unlimited_params_from_template - Expected result: 37, hi\n') 163 164 t = template.Template('{% load custom %}{% inclusion_unlimited_params_from_template 37 42 56 89 %}') 165 self.assertEqual(t.render(c), u'inclusion_unlimited_params_from_template - Expected result: 37, 42, 56, 89\n') 166 167 t = template.Template('{% load custom %}{% inclusion_only_unlimited_params_from_template %}') 168 self.assertEqual(t.render(c), u'inclusion_only_unlimited_params_from_template - Expected result: \n') 169 170 t = template.Template('{% load custom %}{% inclusion_only_unlimited_params_from_template 37 42 56 89 %}') 171 self.assertEqual(t.render(c), u'inclusion_only_unlimited_params_from_template - Expected result: 37, 42, 56, 89\n') 172 94 173 def test_inclusion_tag_registration(self): 95 174 # Test that the decorators preserve the decorated function's docstring, name and attributes. 96 175 self.verify_tag(custom.inclusion_no_params, 'inclusion_no_params') … … class CustomTagTests(TestCase): 98 177 self.verify_tag(custom.inclusion_explicit_no_context, 'inclusion_explicit_no_context') 99 178 self.verify_tag(custom.inclusion_no_params_with_context, 'inclusion_no_params_with_context') 100 179 self.verify_tag(custom.inclusion_params_and_context, 'inclusion_params_and_context') 180 self.verify_tag(custom.inclusion_two_params, 'inclusion_two_params') 181 self.verify_tag(custom.inclusion_one_default, 'inclusion_one_default') 182 self.verify_tag(custom.inclusion_unlimited_params, 'inclusion_unlimited_params') 183 self.verify_tag(custom.inclusion_only_unlimited_params, 'inclusion_only_unlimited_params') 101 184 102 185 def test_15070_current_app(self): 103 186 """ … … class CustomTagTests(TestCase): 141 224 t = template.Template('{% load custom %}{% assignment_params_and_context 37 as var %}The result is: {{ var }}') 142 225 self.assertEqual(t.render(c), u'The result is: assignment_params_and_context - Expected result (context value: 42): 37') 143 226 227 t = template.Template('{% load custom %}{% assignment_two_params 37 42 as var %}The result is: {{ var }}') 228 self.assertEqual(t.render(c), u'The result is: assignment_two_params - Expected result: 37, 42') 229 230 t = template.Template('{% load custom %}{% assignment_one_default 37 as var %}The result is: {{ var }}') 231 self.assertEqual(t.render(c), u'The result is: assignment_one_default - Expected result: 37, hi') 232 233 t = template.Template('{% load custom %}{% assignment_one_default 37 42 as var %}The result is: {{ var }}') 234 self.assertEqual(t.render(c), u'The result is: assignment_one_default - Expected result: 37, 42') 235 236 t = template.Template('{% load custom %}{% assignment_unlimited_params 37 as var %}The result is: {{ var }}') 237 self.assertEqual(t.render(c), u'The result is: assignment_unlimited_params - Expected result: 37, hi') 238 239 t = template.Template('{% load custom %}{% assignment_unlimited_params 37 42 56 89 as var %}The result is: {{ var }}') 240 self.assertEqual(t.render(c), u'The result is: assignment_unlimited_params - Expected result: 37, 42, 56, 89') 241 242 t = template.Template('{% load custom %}{% assignment_only_unlimited_params as var %}The result is: {{ var }}') 243 self.assertEqual(t.render(c), u'The result is: assignment_only_unlimited_params - Expected result: ') 244 245 t = template.Template('{% load custom %}{% assignment_only_unlimited_params 37 42 56 89 as var %}The result is: {{ var }}') 246 self.assertEqual(t.render(c), u'The result is: assignment_only_unlimited_params - Expected result: 37, 42, 56, 89') 247 144 248 self.assertRaisesRegexp(template.TemplateSyntaxError, 145 249 "'assignment_one_param' tag takes at least 2 arguments and the second last argument must be 'as'", 146 250 template.Template, '{% load custom %}{% assignment_one_param 37 %}The result is: {{ var }}') … … class CustomTagTests(TestCase): 153 257 "'assignment_one_param' tag takes at least 2 arguments and the second last argument must be 'as'", 154 258 template.Template, '{% load custom %}{% assignment_one_param 37 ass var %}The result is: {{ var }}') 155 259 260 self.assertRaisesRegexp(template.TemplateSyntaxError, 261 "'assignment_two_params' tag takes 2 argument\(s\)", 262 template.Template, '{% load custom %}{% assignment_two_params 37 42 56 as var %}The result is: {{ var }}') 263 264 self.assertRaisesRegexp(template.TemplateSyntaxError, 265 "'assignment_one_default' tag takes between 1 and 2 arguments", 266 template.Template, '{% load custom %}{% assignment_one_default 37 42 56 as var %}The result is: {{ var }}') 267 268 self.assertRaisesRegexp(template.TemplateSyntaxError, 269 "'assignment_one_default' tag takes between 1 and 2 arguments", 270 template.Template, '{% load custom %}{% assignment_one_default as var %}The result is: {{ var }}') 271 272 self.assertRaisesRegexp(template.TemplateSyntaxError, 273 "'assignment_unlimited_params' tag takes at least 1 argument\(s\)", 274 template.Template, '{% load custom %}{% assignment_unlimited_params as var %}The result is: {{ var }}') 275 156 276 def test_assignment_tag_registration(self): 157 277 # Test that the decorators preserve the decorated function's docstring, name and attributes. 158 278 self.verify_tag(custom.assignment_no_params, 'assignment_no_params') … … class CustomTagTests(TestCase): 160 280 self.verify_tag(custom.assignment_explicit_no_context, 'assignment_explicit_no_context') 161 281 self.verify_tag(custom.assignment_no_params_with_context, 'assignment_no_params_with_context') 162 282 self.verify_tag(custom.assignment_params_and_context, 'assignment_params_and_context') 283 self.verify_tag(custom.assignment_one_default, 'assignment_one_default') 284 self.verify_tag(custom.assignment_two_params, 'assignment_two_params') 285 self.verify_tag(custom.assignment_unlimited_params, 'assignment_unlimited_params') 286 self.verify_tag(custom.assignment_only_unlimited_params, 'assignment_only_unlimited_params') 163 287 164 288 def test_assignment_tag_missing_context(self): 165 289 # That the 'context' parameter must be present when takes_context is True -
tests/regressiontests/templates/templatetags/custom.py
diff --git a/tests/regressiontests/templates/templatetags/custom.py b/tests/regressiontests/templates/templatetags/custom.py index dfa4171..0ed7f27 100644
a b def params_and_context(context, arg): 40 40 return "params_and_context - Expected result (context value: %s): %s" % (context['value'], arg) 41 41 params_and_context.anything = "Expected params_and_context __dict__" 42 42 43 @register.simple_tag 44 def simple_two_params(one, two): 45 """Expected simple_two_params __doc__""" 46 return "simple_two_params - Expected result: %s, %s" % (one, two) 47 simple_two_params.anything = "Expected simple_two_params __dict__" 48 49 @register.simple_tag 50 def simple_one_default(one, two='hi'): 51 """Expected simple_one_default __doc__""" 52 return "simple_one_default - Expected result: %s, %s" % (one, two) 53 simple_one_default.anything = "Expected simple_one_default __dict__" 54 55 @register.simple_tag 56 def simple_unlimited_params(one, two='hi', *args): 57 """Expected simple_unlimited_params __doc__""" 58 return "simple_unlimited_params - Expected result: %s" % (', '.join([unicode(arg) for arg in [one, two] + list(args)])) 59 simple_unlimited_params.anything = "Expected simple_unlimited_params __dict__" 60 61 @register.simple_tag 62 def simple_only_unlimited_params(*args): 63 """Expected simple_only_unlimited_params __doc__""" 64 return "simple_only_unlimited_params - Expected result: %s" % ', '.join([unicode(arg) for arg in args]) 65 simple_only_unlimited_params.anything = "Expected simple_only_unlimited_params __dict__" 66 43 67 @register.inclusion_tag('inclusion.html') 44 68 def inclusion_no_params(): 45 69 """Expected inclusion_no_params __doc__""" … … def inclusion_params_and_context_from_template(context, arg): 100 124 return {"result" : "inclusion_params_and_context_from_template - Expected result (context value: %s): %s" % (context['value'], arg)} 101 125 inclusion_params_and_context_from_template.anything = "Expected inclusion_params_and_context_from_template __dict__" 102 126 127 @register.inclusion_tag('inclusion.html') 128 def inclusion_two_params(one, two): 129 """Expected inclusion_two_params __doc__""" 130 return {"result": "inclusion_two_params - Expected result: %s, %s" % (one, two)} 131 inclusion_two_params.anything = "Expected inclusion_two_params __dict__" 132 133 @register.inclusion_tag(get_template('inclusion.html')) 134 def inclusion_two_params_from_template(one, two): 135 """Expected inclusion_two_params_from_template __doc__""" 136 return {"result": "inclusion_two_params_from_template - Expected result: %s, %s" % (one, two)} 137 inclusion_two_params_from_template.anything = "Expected inclusion_two_params_from_template __dict__" 138 139 @register.inclusion_tag('inclusion.html') 140 def inclusion_one_default(one, two='hi'): 141 """Expected inclusion_one_default __doc__""" 142 return {"result": "inclusion_one_default - Expected result: %s, %s" % (one, two)} 143 inclusion_one_default.anything = "Expected inclusion_one_default __dict__" 144 145 @register.inclusion_tag(get_template('inclusion.html')) 146 def inclusion_one_default_from_template(one, two='hi'): 147 """Expected inclusion_one_default_from_template __doc__""" 148 return {"result": "inclusion_one_default_from_template - Expected result: %s, %s" % (one, two)} 149 inclusion_one_default_from_template.anything = "Expected inclusion_one_default_from_template __dict__" 150 151 @register.inclusion_tag('inclusion.html') 152 def inclusion_unlimited_params(one, two='hi', *args): 153 """Expected inclusion_unlimited_params __doc__""" 154 return {"result": "inclusion_unlimited_params - Expected result: %s" % (', '.join([unicode(arg) for arg in [one, two] + list(args)]))} 155 inclusion_unlimited_params.anything = "Expected inclusion_unlimited_params __dict__" 156 157 @register.inclusion_tag(get_template('inclusion.html')) 158 def inclusion_unlimited_params_from_template(one, two='hi', *args): 159 """Expected inclusion_unlimited_params_from_template __doc__""" 160 return {"result": "inclusion_unlimited_params_from_template - Expected result: %s" % (', '.join([unicode(arg) for arg in [one, two] + list(args)]))} 161 inclusion_unlimited_params_from_template.anything = "Expected inclusion_unlimited_params_from_template __dict__" 162 163 @register.inclusion_tag('inclusion.html') 164 def inclusion_only_unlimited_params(*args): 165 """Expected inclusion_only_unlimited_params __doc__""" 166 return {"result": "inclusion_only_unlimited_params - Expected result: %s" % (', '.join([unicode(arg) for arg in args]))} 167 inclusion_only_unlimited_params.anything = "Expected inclusion_only_unlimited_params __dict__" 168 169 @register.inclusion_tag(get_template('inclusion.html')) 170 def inclusion_only_unlimited_params_from_template(*args): 171 """Expected inclusion_only_unlimited_params_from_template __doc__""" 172 return {"result": "inclusion_only_unlimited_params_from_template - Expected result: %s" % (', '.join([unicode(arg) for arg in args]))} 173 inclusion_only_unlimited_params_from_template.anything = "Expected inclusion_only_unlimited_params_from_template __dict__" 174 103 175 @register.simple_tag(takes_context=True) 104 176 def current_app(context): 105 177 return "%s" % context.current_app … … def assignment_params_and_context(context, arg): 146 218 return "assignment_params_and_context - Expected result (context value: %s): %s" % (context['value'], arg) 147 219 assignment_params_and_context.anything = "Expected assignment_params_and_context __dict__" 148 220 221 @register.assignment_tag 222 def assignment_two_params(one, two): 223 """Expected assignment_two_params __doc__""" 224 return "assignment_two_params - Expected result: %s, %s" % (one, two) 225 assignment_two_params.anything = "Expected assignment_two_params __dict__" 226 227 @register.assignment_tag 228 def assignment_one_default(one, two='hi'): 229 """Expected assignment_one_default __doc__""" 230 return "assignment_one_default - Expected result: %s, %s" % (one, two) 231 assignment_one_default.anything = "Expected assignment_one_default __dict__" 232 233 @register.assignment_tag 234 def assignment_unlimited_params(one, two='hi', *args): 235 """Expected assignment_unlimited_params __doc__""" 236 return "assignment_unlimited_params - Expected result: %s" % (', '.join([unicode(arg) for arg in [one, two] + list(args)])) 237 assignment_unlimited_params.anything = "Expected assignment_unlimited_params __dict__" 238 239 @register.assignment_tag 240 def assignment_only_unlimited_params(*args): 241 """Expected assignment_only_unlimited_params __doc__""" 242 return "assignment_only_unlimited_params - Expected result: %s" % ', '.join([unicode(arg) for arg in args]) 243 assignment_only_unlimited_params.anything = "Expected assignment_only_unlimited_params __dict__" 244 149 245 register.simple_tag(lambda x: x - 1, name='minusone') 150 246 151 247 @register.simple_tag(name='minustwo')