Code

Ticket #2016: fix2016.patch

File fix2016.patch, 7.0 KB (added by mk, 4 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): 
    848848            return '' 
    849849        return _render_value_in_context(output, context) 
    850850 
    851 def generic_tag_compiler(params, defaults, name, node_class, parser, token): 
    852     "Returns a template.Node subclass." 
    853     bits = token.split_contents()[1:] 
     851def match_number_of_arguments(bits, params, defaults, name): 
    854852    bmax = len(params) 
    855853    def_len = defaults and len(defaults) or 0 
    856854    bmin = bmax - def_len 
    def generic_tag_compiler(params, defaults, name, node_class, parser, token): 
    860858        else: 
    861859            message = "%s takes between %s and %s arguments" % (name, bmin, bmax) 
    862860        raise TemplateSyntaxError(message) 
     861 
     862def 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) 
    863866    return node_class(bits) 
    864867 
    865868class Library(object): 
    class Library(object): 
    931934        self.tag(getattr(func, "_decorated_function", func).__name__, compile_func) 
    932935        return func 
    933936 
     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 
    934969    def inclusion_tag(self, file_name, context_class=Context, takes_context=False): 
    935970        def dec(func): 
    936971            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:: 
    858858The difference here is that ``do_current_time()`` grabs the format string and 
    859859the variable name, passing both to ``CurrentTimeNode3``. 
    860860 
     861Shortcut for loading objects into template variables 
     862~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     863 
     864.. versionadded: 1.2 
     865 
     866If you only need to retrieve and store an object in a template variable, it 
     867might seem cumbersome to write both a renderer and a compilation function 
     868for such an easy task. 
     869 
     870That is why Django provides yet another shortcut -- ``object_tag`` -- which 
     871makes it easy to write tags that loads objects into template variables. 
     872 
     873Its use is very similar to ``simple_tag`` in the way that it takes care of 
     874all the argument parsing for you, and only requires a single return value -- 
     875the object you'd like to insert into the template variable. 
     876 
     877Example:: 
     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 
     884Or 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 
     890This tag returns the latest ``Poll``-objects, sorted by descending order, and 
     891limited by the value of ``max_num``. Its use in a template would look like 
     892this: 
     893 
     894.. code-block:: html+django 
     895 
     896    {% get_latest_polls 5 as latest_polls %} 
     897 
     898Which would retrieve the 5 latest polls and store them inside a template 
     899variable named "latest_polls". 
     900 
     901Note 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 
     907Where ``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 
     909should be stored. 
     910 
    861911Parsing until another block tag 
    862912~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    863913 
  • 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
    - +  
     1object_tag_tests = """ 
     2>>> t = template.Template('{% load custom %}{% get_meaning_of_life as answer %}{{ answer }}') 
     3>>> t.render(template.Context()) 
     4u"42" 
     5>>> t = template.Template('{% load custom %}{% get_mascot_with "awesomeness" "magical powers" as pony %}{{ pony }}') 
     6>>> t.render(template.Context()) 
     7u"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'})) 
     10u"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) 
    99 
    1010register.filter(trim) 
    1111 
     12def get_meaning_of_life(): 
     13    return 42 
     14register.object_tag(get_meaning_of_life) 
     15 
     16def get_mascot_with(power_one, power_two): 
     17    return 'This mascot is filled with %s and %s' % (power_one, power_two) 
     18register.object_tag(get_mascot_with) 
     19 
     20def count(char, word): 
     21    return word.count(char) 
     22register.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 
    2727from unicode import unicode_tests 
    2828from nodelist import NodelistTest 
    2929from smartif import * 
     30from object_tag import object_tag_tests 
    3031 
    3132try: 
    3233    from loaders import * 
    __test__ = { 
    4344    'filter_parsing': filter_parsing, 
    4445    'variable_parsing': variable_parsing, 
    4546    'custom_filters': custom_filters, 
     47    'object_tag': object_tag_tests, 
    4648} 
    4749 
    4850#################################