Ticket #11832: 11832.0.patch

File 11832.0.patch, 5.0 KB (added by mpaolini, 6 years ago)
  • django/template/__init__.py

     
    173173            for subnode in node:
    174174                yield subnode
    175175
    176     def render(self, context):
     176    def render(self, context, block_name=None):
    177177        "Display stage -- can be called many times"
    178178        return self.nodelist.render(context)
    179179
  • django/template/loader_tags.py

     
    11from django.template import TemplateSyntaxError, TemplateDoesNotExist, Variable
    2 from django.template import Library, Node, TextNode
     2from django.template import Library, Node, TextNode, NodeList
    33from django.template.loader import get_template, get_template_from_string, find_template_source
    44from django.conf import settings
    55from django.utils.safestring import mark_safe
     
    9696                parent_block.nodelist = block_node.nodelist
    9797        return compiled_parent.render(context)
    9898
     99def get_block_nodes(template, block_name):
     100    for n in template.nodelist:
     101        if isinstance(n, BlockNode) and n.name == block_name:
     102            return n.nodelist
     103    return NodeList()
     104   
    99105class ConstantIncludeNode(Node):
    100     def __init__(self, template_path):
     106    def __init__(self, template_path, block_name=None):
    101107        try:
     108            self.block_name = block_name
    102109            t = get_template(template_path)
    103110            self.template = t
    104111        except:
     
    108115
    109116    def render(self, context):
    110117        if self.template:
     118            if self.block_name:
     119                nodelist = get_block_nodes(self.template, self.block_name)
     120                return nodelist.render(context)
    111121            return self.template.render(context)
    112122        else:
    113123            return ''
    114124
    115125class IncludeNode(Node):
    116     def __init__(self, template_name):
     126    def __init__(self, template_name, block_name=None):
    117127        self.template_name = Variable(template_name)
     128        self.block_name = block_name
    118129
    119130    def render(self, context):
    120131        try:
    121132            template_name = self.template_name.resolve(context)
    122133            t = get_template(template_name)
     134            if self.block_name:
     135                nodelist = get_block_nodes(t, self.block_name)
     136                return nodelist.render(context)
    123137            return t.render(context)
    124138        except TemplateSyntaxError, e:
    125139            if settings.TEMPLATE_DEBUG:
     
    156170    uses the literal value "base" as the name of the parent template to extend,
    157171    or ``{% extends variable %}`` uses the value of ``variable`` as either the
    158172    name of the parent template to extend (if it evaluates to a string) or as
    159     the parent tempate itelf (if it evaluates to a Template object).
     173    the parent tempate itself (if it evaluates to a Template object).
    160174    """
    161175    bits = token.split_contents()
    162176    if len(bits) != 2:
     
    177191
    178192    Example::
    179193
    180         {% include "foo/some_include" %}
     194        {% include "foo/some_include" ["block_name"] %}
    181195    """
    182196    bits = token.split_contents()
    183     if len(bits) != 2:
    184         raise TemplateSyntaxError, "%r tag takes one argument: the name of the template to be included" % bits[0]
     197    if len(bits) < 2 or len(bits) > 3:
     198        raise TemplateSyntaxError, "%r tag takes at least one argument: the name of the template to be included" % bits[0]
    185199    path = bits[1]
     200    if len(bits) == 3:
     201        block = bits[2]
     202        if path[0] in ('"', "'") and path[-1] == path[0]:
     203            block = block[1:-1]
     204        else:
     205            # TODO: handle block name as variable
     206            raise TemplateSyntaxError, "%r must be enclosed by quotes" % block
     207    else:
     208        block = None
    186209    if path[0] in ('"', "'") and path[-1] == path[0]:
    187         return ConstantIncludeNode(path[1:-1])
    188     return IncludeNode(bits[1])
     210        return ConstantIncludeNode(path[1:-1], block)
     211    return IncludeNode(path, block)
    189212
    190213register.tag('block', do_block)
    191214register.tag('extends', do_extends)
  • tests/regressiontests/templates/tests.py

     
    697697            'include04': ('a{% include "nonexistent" %}b', {}, "ab"),
    698698            'include 05': ('template with a space', {}, 'template with a space'),
    699699            'include06': ('{% include "include 05"%}', {}, 'template with a space'),
     700            'included07': ('{% block head %}head here{% endblock %} body {% block tail %}tail here{% endblock %}', {}, 'head here body tail here'),
     701            'include07-1': ('{% include "included07" "head" %}', {}, 'head here'),
     702            'include07-2': ('{% include "included07" "tail" %}', {}, 'tail here'),
    700703
    701704            ### NAMED ENDBLOCKS #######################################################
    702705
Back to Top