Ticket #7817: ticket7817_r13997.diff

File ticket7817_r13997.diff, 6.5 KB (added by Łukasz Rekucki, 14 years ago)

Patch without "with" related stuff. Added docs and one more test.

  • django/template/loader_tags.py

    diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py
    index b8bc741..db54c70 100644
    a b  
    11from django.template import TemplateSyntaxError, TemplateDoesNotExist, Variable
    22from django.template import Library, Node, TextNode
    33from django.template.loader import get_template
     4from django.template.defaulttags import kwarg_re
    45from django.conf import settings
    56from django.utils.safestring import mark_safe
    67
    class ExtendsNode(Node):  
    125126        return compiled_parent._render(context)
    126127
    127128class ConstantIncludeNode(Node):
    128     def __init__(self, template_path):
     129    def __init__(self, template_path, extra_context={}):
    129130        try:
    130131            t = get_template(template_path)
    131132            self.template = t
     133            self.extra_context = extra_context
    132134        except:
    133135            if settings.TEMPLATE_DEBUG:
    134136                raise
    class ConstantIncludeNode(Node):  
    136138
    137139    def render(self, context):
    138140        if self.template:
    139             return self.template.render(context)
     141            values = [(name, var.resolve(context)) for name, var
     142                        in self.extra_context.iteritems()]
     143            context.update(dict(values))
     144            output = self.template.render(context)
     145            context.pop()
     146            return output
    140147        else:
    141148            return ''
    142149
    143150class IncludeNode(Node):
    144     def __init__(self, template_name):
     151    def __init__(self, template_name, extra_context={}):
    145152        self.template_name = Variable(template_name)
     153        self.extra_context = extra_context
    146154
    147155    def render(self, context):
    148156        try:
    149157            template_name = self.template_name.resolve(context)
    150158            t = get_template(template_name)
    151             return t.render(context)
    152         except TemplateSyntaxError, e:
     159            values = [(name, var.resolve(context)) for name, var
     160                        in self.extra_context.iteritems()]
     161            context.update(dict(values))
     162            output = t.render(context)
     163            context.pop()
     164            return output
     165        except TemplateSyntaxError:
    153166            if settings.TEMPLATE_DEBUG:
    154167                raise
    155168            return ''
    def do_extends(parser, token):  
    201214
    202215def do_include(parser, token):
    203216    """
    204     Loads a template and renders it with the current context.
     217    Loads a template and renders it with the current context. You can pass
     218    additional context using keyword arguments.
    205219
    206220    Example::
    207221
    208222        {% include "foo/some_include" %}
     223        {% include "foo/some_include" with bar="BAZZ!" %}
     224
    209225    """
    210226    bits = token.split_contents()
    211     if len(bits) != 2:
    212         raise TemplateSyntaxError("%r tag takes one argument: the name of the template to be included" % bits[0])
     227    if len(bits) < 2:
     228        raise TemplateSyntaxError("%r tag takes at least one argument: the name of the template to be included." % bits[0])
     229    namemap = {}
     230    if len(bits) > 2:
     231        if bits[2] == 'with':
     232            for bit in bits[3:]:
     233                match = kwarg_re.match(bit)
     234                if not match:
     235                    raise TemplateSyntaxError("Malformed arguments to %r tag." % bits[0])
     236                name, value = match.groups()
     237                if not name:
     238                    raise TemplateSyntaxError('''"with" part of %r tag accepts only keyword arguments.''' % bits[0])
     239                if name in namemap:
     240                    raise TemplateSyntaxError("Tried to bind value to name %r more than once." % name)
     241                namemap[name] = parser.compile_filter(value)
     242            if not namemap:
     243                raise TemplateSyntaxError('''"with" in %r tag needs at least one keyword argument.''' % bits[0])
     244        else:
     245            raise TemplateSyntaxError('''Invalid option %r for %r tag.''' % (bits[2], bits[0]))
    213246    path = bits[1]
    214247    if path[0] in ('"', "'") and path[-1] == path[0]:
    215         return ConstantIncludeNode(path[1:-1])
    216     return IncludeNode(bits[1])
     248        return ConstantIncludeNode(path[1:-1], extra_context=namemap)
     249    return IncludeNode(bits[1], extra_context=namemap)
    217250
    218251register.tag('block', do_block)
    219252register.tag('extends', do_extends)
  • docs/ref/templates/builtins.txt

    diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
    index a20ab17..6e84225 100644
    a b including it. This example produces the output ``"Hello, John"``:  
    623623
    624624See also: ``{% ssi %}``.
    625625
     626.. versionadded:: 1.3
     627
     628You can pass additional context to the template using keyword arguments::
     629
     630    {% include "name_snippet.html" person="Jane" %}
     631
     632This is pretty much syntactic sugar for wrapping :ttag:`include`
     633with a :ttag:`with` tag.
     634
    626635.. note::
    627636    The :ttag:`include` tag should be considered as an implementation of
    628637    "render this subtemplate and include the HTML", not as "parse this
  • tests/regressiontests/templates/tests.py

    diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
    index 9e2d175..902f5f0 100644
    a b class Templates(unittest.TestCase):  
    923923            'include 05': ('template with a space', {}, 'template with a space'),
    924924            'include06': ('{% include "include 05"%}', {}, 'template with a space'),
    925925
     926            # extra inline context
     927            'include07': ('{% include "basic-syntax02" with headline="Inline" %}', {'headline': 'Included'}, 'Inline'),
     928            'include08': ('{% include headline with headline="Dynamic" %}', {'headline': 'basic-syntax02'}, 'Dynamic'),
     929            'include09': ('{{ first }}--{% include "basic-syntax03" with first=second|lower|upper second=first|upper %}--{{ second }}', {'first': 'Ul', 'second': 'lU'}, 'Ul--LU --- UL--lU'),
     930
     931            'include-error01': ('{% include "basic-syntax01" with %}', {}, template.TemplateSyntaxError),
     932            'include-error02': ('{% include "basic-syntax01" with "no key" %}', {}, template.TemplateSyntaxError),
     933            'include-error03': ('{% include "basic-syntax01" with dotted.arg="error" %}', {}, template.TemplateSyntaxError),
     934            'include-error04': ('{% include "basic-syntax01" something_random %}', {}, template.TemplateSyntaxError),
     935            'include-error05': ('{% include "basic-syntax01" foo="duplicate" foo="key" %}', {}, template.TemplateSyntaxError),
     936
    926937            ### NAMED ENDBLOCKS #######################################################
    927938
    928939            # Basic test
Back to Top