Ticket #2016: object_tag-combined-patch.diff
File object_tag-combined-patch.diff, 6.8 KB (added by , 15 years ago) |
---|
-
django/template/__init__.py
diff --git a/django/template/__init__.py b/django/template/__init__.py index 5493e5b..03e2a6c 100644
a b class VariableNode(Node): 830 830 return '' 831 831 return _render_value_in_context(output, context) 832 832 833 def generic_tag_compiler(params, defaults, name, node_class, parser, token): 834 "Returns a template.Node subclass." 835 bits = token.split_contents()[1:] 833 def match_number_of_arguments(bits, params, defaults, name): 836 834 bmax = len(params) 837 835 def_len = defaults and len(defaults) or 0 838 836 bmin = bmax - def_len … … def generic_tag_compiler(params, defaults, name, node_class, parser, token): 842 840 else: 843 841 message = "%s takes between %s and %s arguments" % (name, bmin, bmax) 844 842 raise TemplateSyntaxError(message) 843 844 def generic_tag_compiler(params, defaults, name, node_class, parser, token): 845 "Returns a template.Node subclass." 846 bits = token.split_contents()[1:] 847 match_number_of_arguments(bits, params, defaults, name) 845 848 return node_class(bits) 846 849 847 850 class Library(object): … … class Library(object): 913 916 self.tag(getattr(func, "_decorated_function", func).__name__, compile_func) 914 917 return func 915 918 919 def object_tag(self, func): 920 params, xx, xxx, defaults = getargspec(func) 921 922 class ObjectNode(Node): 923 def __init__(self, vars_to_resolve, var_name): 924 self.vars_to_resolve = map(Variable, vars_to_resolve) 925 self.var_name = var_name 926 927 def render(self, context): 928 resolved_vars = [var.resolve(context) for var in self.vars_to_resolve] 929 obj = func(*resolved_vars) 930 context[self.var_name] = obj 931 return '' 932 933 def object_tag_compiler(params, defaults, name, node_class, parser, token): 934 bits = token.split_contents()[1:] 935 936 if len(bits) < 2 or bits[-2] != 'as': 937 raise TemplateSyntaxError("the next to last argument to %s must be 'as'" % name) 938 939 var_name, bits = bits[-1], bits[:-2] 940 match_number_of_arguments(bits, params, defaults, name) 941 942 return node_class(bits, var_name) 943 944 compile_func = curry(object_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, ObjectNode) 945 compile_func.__doc__ = func.__doc__ 946 947 self.tag(getattr(func, "_decorated_function", func).__name__, compile_func) 948 949 return func 950 916 951 def inclusion_tag(self, file_name, context_class=Context, takes_context=False): 917 952 def dec(func): 918 953 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 c6f7677..6b78711 100644
a b class, like so:: 783 783 The difference here is that ``do_current_time()`` grabs the format string and 784 784 the variable name, passing both to ``CurrentTimeNode3``. 785 785 786 Shortcut for loading objects into template variables 787 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 788 789 .. versionadded: 1.2 790 791 If you only need to retrieve and store an object in a template variable, it 792 might seem cumbersome to write both a renderer and a compilation function 793 for such an easy task. 794 795 That is why Django provides yet another shortcut -- ``object_tag`` -- which 796 makes it easy to write tags that loads objects into template variables. 797 798 Its use is very similar to ``simple_tag`` in the way that it takes care of 799 all the argument parsing for you, and only requires a single return value -- 800 the object you'd like to insert into the template variable. 801 802 Example:: 803 804 def get_latest_polls(max_num): 805 return Poll.objects.order_by('-pub_date')[:max_num] 806 807 register.object_tag(get_latest_polls) 808 809 Or if you wish to use the Python 2.4 decorator syntax:: 810 811 @register.object_tag 812 def get_latest_polls(max_num): 813 return Poll.objects.order_by('-pub_date')[:max_num] 814 815 This tag returns the latest ``Poll``-objects, sorted by descending order, and 816 limited by the value of ``max_num``. Its use in a template would look like 817 this: 818 819 .. code-block:: html+django 820 821 {% get_latest_polls 5 as latest_polls %} 822 823 Which would retrieve the 5 latest polls and store them inside a template 824 variable named "latest_polls". 825 826 Note that the following syntax is *mandatory* for all object_tag's: 827 828 .. code-block:: html+django 829 830 {% tag_name [args] as <var_name> %} 831 832 Where ``args`` is the arguments for the templatetag ``tag_name``, and 833 ``var_name`` is the name of the template variable in which the returned object 834 should be stored. 835 786 836 Parsing until another block tag 787 837 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 788 838 -
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 9c01b49..0badc86 100644
a b from context import context_tests 24 24 from custom import custom_filters 25 25 from parser import filter_parsing, variable_parsing 26 26 from unicode import unicode_tests 27 from object_tag import object_tag_tests 27 28 28 29 try: 29 30 from loaders import * … … __test__ = { 38 39 'context': context_tests, 39 40 'filter_parsing': filter_parsing, 40 41 'custom_filters': custom_filters, 42 'object_tag': object_tag_tests, 41 43 } 42 44 43 45 #################################