Ticket #2016: fix2016.patch
File fix2016.patch, 7.0 KB (added by , 14 years ago) |
---|
-
django/template/__init__.py
commit bb81dd7ed59a6ec1f493e255b9dbbe7afa1dee53 Author: Matthias Kestenholz <mk@spinlock.ch> Date: Thu Oct 7 13:09:17 2010 +0200 WIP diff --git a/django/template/__init__.py b/django/template/__init__.py index c316786..75e81c4 100644
a b class VariableNode(Node): 848 848 return '' 849 849 return _render_value_in_context(output, context) 850 850 851 def generic_tag_compiler(params, defaults, name, node_class, parser, token): 852 "Returns a template.Node subclass." 853 bits = token.split_contents()[1:] 851 def match_number_of_arguments(bits, params, defaults, name): 854 852 bmax = len(params) 855 853 def_len = defaults and len(defaults) or 0 856 854 bmin = bmax - def_len … … def generic_tag_compiler(params, defaults, name, node_class, parser, token): 860 858 else: 861 859 message = "%s takes between %s and %s arguments" % (name, bmin, bmax) 862 860 raise TemplateSyntaxError(message) 861 862 def generic_tag_compiler(params, defaults, name, node_class, parser, token): 863 "Returns a template.Node subclass." 864 bits = token.split_contents()[1:] 865 match_number_of_arguments(bits, params, defaults, name) 863 866 return node_class(bits) 864 867 865 868 class Library(object): … … class Library(object): 931 934 self.tag(getattr(func, "_decorated_function", func).__name__, compile_func) 932 935 return func 933 936 937 def object_tag(self, func): 938 params, xx, xxx, defaults = getargspec(func) 939 940 class ObjectNode(Node): 941 def __init__(self, vars_to_resolve, var_name): 942 self.vars_to_resolve = map(Variable, vars_to_resolve) 943 self.var_name = var_name 944 945 def render(self, context): 946 resolved_vars = [var.resolve(context) for var in self.vars_to_resolve] 947 obj = func(*resolved_vars) 948 context[self.var_name] = obj 949 return '' 950 951 def object_tag_compiler(params, defaults, name, node_class, parser, token): 952 bits = token.split_contents()[1:] 953 954 if len(bits) < 2 or bits[-2] != 'as': 955 raise TemplateSyntaxError("the next to last argument to %s must be 'as'" % name) 956 957 var_name, bits = bits[-1], bits[:-2] 958 match_number_of_arguments(bits, params, defaults, name) 959 960 return node_class(bits, var_name) 961 962 compile_func = curry(object_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, ObjectNode) 963 compile_func.__doc__ = func.__doc__ 964 965 self.tag(getattr(func, "_decorated_function", func).__name__, compile_func) 966 967 return func 968 934 969 def inclusion_tag(self, file_name, context_class=Context, takes_context=False): 935 970 def dec(func): 936 971 params, xx, xxx, defaults = getargspec(func) -
docs/howto/custom-template-tags.txt
diff --git a/docs/howto/custom-template-tags.txt b/docs/howto/custom-template-tags.txt index c4d2315..43c8812 100644
a b class, like so:: 858 858 The difference here is that ``do_current_time()`` grabs the format string and 859 859 the variable name, passing both to ``CurrentTimeNode3``. 860 860 861 Shortcut for loading objects into template variables 862 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 863 864 .. versionadded: 1.2 865 866 If you only need to retrieve and store an object in a template variable, it 867 might seem cumbersome to write both a renderer and a compilation function 868 for such an easy task. 869 870 That is why Django provides yet another shortcut -- ``object_tag`` -- which 871 makes it easy to write tags that loads objects into template variables. 872 873 Its use is very similar to ``simple_tag`` in the way that it takes care of 874 all the argument parsing for you, and only requires a single return value -- 875 the object you'd like to insert into the template variable. 876 877 Example:: 878 879 def get_latest_polls(max_num): 880 return Poll.objects.order_by('-pub_date')[:max_num] 881 882 register.object_tag(get_latest_polls) 883 884 Or if you wish to use the Python 2.4 decorator syntax:: 885 886 @register.object_tag 887 def get_latest_polls(max_num): 888 return Poll.objects.order_by('-pub_date')[:max_num] 889 890 This tag returns the latest ``Poll``-objects, sorted by descending order, and 891 limited by the value of ``max_num``. Its use in a template would look like 892 this: 893 894 .. code-block:: html+django 895 896 {% get_latest_polls 5 as latest_polls %} 897 898 Which would retrieve the 5 latest polls and store them inside a template 899 variable named "latest_polls". 900 901 Note that the following syntax is *mandatory* for all object_tag's: 902 903 .. code-block:: html+django 904 905 {% tag_name [args] as <var_name> %} 906 907 Where ``args`` is the arguments for the templatetag ``tag_name``, and 908 ``var_name`` is the name of the template variable in which the returned object 909 should be stored. 910 861 911 Parsing until another block tag 862 912 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 863 913 -
new file tests/regressiontests/templates/object_tag.py
diff --git a/tests/regressiontests/templates/object_tag.py b/tests/regressiontests/templates/object_tag.py new file mode 100644 index 0000000..5f67b9e
- + 1 object_tag_tests = """ 2 >>> t = template.Template('{% load custom %}{% get_meaning_of_life as answer %}{{ answer }}') 3 >>> t.render(template.Context()) 4 u"42" 5 >>> t = template.Template('{% load custom %}{% get_mascot_with "awesomeness" "magical powers" as pony %}{{ pony }}') 6 >>> t.render(template.Context()) 7 u"This mascot is filled with awesomeness and magical powers" 8 >>> t = template.Template('{% load custom %}{% count "e" word as num %}{{ num }}') 9 >>> t.render(template.Context({'word': 'beefcake'})) 10 u"3" 11 """ -
tests/regressiontests/templates/templatetags/custom.py
diff --git a/tests/regressiontests/templates/templatetags/custom.py b/tests/regressiontests/templates/templatetags/custom.py index fdf8d10..bbb8c08 100644
a b trim = stringfilter(trim) 9 9 10 10 register.filter(trim) 11 11 12 def get_meaning_of_life(): 13 return 42 14 register.object_tag(get_meaning_of_life) 15 16 def get_mascot_with(power_one, power_two): 17 return 'This mascot is filled with %s and %s' % (power_one, power_two) 18 register.object_tag(get_mascot_with) 19 20 def count(char, word): 21 return word.count(char) 22 register.object_tag(count) -
tests/regressiontests/templates/tests.py
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index 9e2d175..1a36e2d 100644
a b from parser import token_parsing, filter_parsing, variable_parsing 27 27 from unicode import unicode_tests 28 28 from nodelist import NodelistTest 29 29 from smartif import * 30 from object_tag import object_tag_tests 30 31 31 32 try: 32 33 from loaders import * … … __test__ = { 43 44 'filter_parsing': filter_parsing, 44 45 'variable_parsing': variable_parsing, 45 46 'custom_filters': custom_filters, 47 'object_tag': object_tag_tests, 46 48 } 47 49 48 50 #################################