Code

Ticket #2778: includeblock.patch

File includeblock.patch, 5.6 KB (added by SmileyChris, 8 years ago)

patch including tests and documentation

  • django/template/loader_tags.py

     
    1 from django.template import TemplateSyntaxError, TemplateDoesNotExist, resolve_variable 
     1from django.template import TemplateSyntaxError, TemplateDoesNotExist, VariableDoesNotExist, resolve_variable 
    22from django.template import Library, Node 
    33from django.template.loader import get_template, get_template_from_string, find_template_source 
    44from django.conf import settings 
     
    113113        except: 
    114114            return '' # Fail silently for invalid included templates. 
    115115 
     116class IncludeBlockNode(Node): 
     117    def __init__(self, template_name, block_name, template_dirs=None): 
     118        self.template_name = template_name 
     119        self.block_name = block_name 
     120        self.template_dirs = template_dirs 
     121 
     122    def render(self, context): 
     123        try: 
     124            template_name = resolve_variable(self.template_name, context) 
     125            block_name = resolve_variable(self.block_name, context) 
     126        except VariableDoesNotExist: 
     127            # Fail silently if either variable can not be resolved. 
     128            return '' 
     129        try: 
     130            template = get_template(template_name) 
     131        except TemplateSyntaxError, e: 
     132            if settings.TEMPLATE_DEBUG: 
     133                raise 
     134            return '' 
     135        except: 
     136            return '' # Fail silently for invalid included template. 
     137        for block_node in template.nodelist.get_nodes_by_type(BlockNode): 
     138            if block_name == block_node.name: 
     139                # Block matches, render it. 
     140                return block_node.render(context) 
     141        # No matching block was found. 
     142        return '' 
     143 
    116144def do_block(parser, token): 
    117145    """ 
    118146    Define a block that can be overridden by child templates. 
     
    172200        return ConstantIncludeNode(path[1:-1]) 
    173201    return IncludeNode(bits[1]) 
    174202 
     203def do_includeblock(parser, token): 
     204    """ 
     205    Loads a block from another template and renders it with the current  
     206    context. The first argument is the template name, the second is the block. 
     207    Both can be variables rendered from the context or given as constants by 
     208    surrounding with quotes. 
     209     
     210    Example:: 
     211     
     212        {% includeblock "foo/some_include.htm" "bar_block" %} 
     213    """ 
     214    bits = token.split_contents() 
     215    if len(bits) != 3: 
     216        raise TemplateSyntaxError, "%r tag takes two arguments: the name of the template and the block to be included" % bits[0] 
     217    return IncludeBlockNode(*bits[1:]) 
     218 
    175219register.tag('block', do_block) 
    176220register.tag('extends', do_extends) 
    177221register.tag('include', do_include) 
     222register.tag('includeblock', do_includeblock) 
  • docs/templates.txt

     
    577577 
    578578See also: ``{% ssi %}``. 
    579579 
     580includeblock 
     581~~~~~~~~~~~~ 
     582 
     583Similar to ``include`` but rather than rendering the entire template, this 
     584renders a specific ``block`` of the given template with the current context. 
     585 
     586Both the template name and the block name can either be variables or 
     587hard-coded (quoted) strings. 
     588 
     589This example includes the "navigation" block of the template "main.htm":: 
     590 
     591        {% includeblock "main.htm" "navigation" %} 
     592 
    580593load 
    581594~~~~ 
    582595 
  • tests/regressiontests/templates/tests.py

     
    418418            # Inheritance from local context with variable parent template 
    419419            'inheritance25': ("{% extends context_template.1 %}{% block first %}2{% endblock %}{% block second %}4{% endblock %}", {'context_template': [template.Template("Wrong"), template.Template("1{% block first %}_{% endblock %}3{% block second %}_{% endblock %}")]}, '1234'), 
    420420 
     421            ### INCLUDEBLOCK TAG ###################################################### 
     422             
     423            # Loading a block tag 
     424            'includeblock01': ('1{% includeblock "inheritance02" "first" %}3', {}, '123'), 
     425             
     426            # Loading a block tag using the template name as a context variable 
     427            'includeblock02': ('3{% includeblock template_name "second" %}5', {'template_name': 'inheritance02'}, '345'), 
     428 
     429            # Loading a block tag using the block name as a context variable 
     430            'includeblock03': ('3{% includeblock "inheritance02" block_name %}5', {'block_name': 'second'}, '345'), 
     431 
     432            # Loading a block tag using context variables 
     433            'includeblock04': ('3{% includeblock template_name block_name %}5', {'template_name': 'inheritance02', 'block_name': 'second'}, '345'), 
     434 
     435            # Invalid template 
     436            'includeblock05': ('a{% includeblock "not a real template" "blockname" %}b', {}, 'ab'), 
     437             
     438            # Invalid block 
     439            'includeblock06': ('b{% includeblock "inheritance02" "invalidblockname" %}c', {}, 'bc'), 
     440             
     441            # Invalid template context variable 
     442            'includeblock07': ('a{% includeblock invalidtemplatename "blockname" %}b', {}, 'ab'), 
     443             
     444            # Invalid block context variable 
     445            'includeblock08': ('b{% includeblock "inheritance02" invalidblockname %}c', {}, 'bc'), 
     446             
    421447            ### I18N ################################################################## 
    422448 
    423449            # {% spaceless %} tag