def handle_extendsnode(extendsnode, block_context=None, original=None): """Create a copy of Node tree of a derived template replacing all blocks tags with the nodes of appropriate blocks. Also handles {{ block.super }} tags. """ if block_context is None: block_context = BlockContext() blocks = dict((n.name, n) for n in extendsnode.nodelist.get_nodes_by_type(BlockNode)) block_context.add_blocks(blocks) # Note: we pass an empty context when we find the parent, this breaks # inheritance using variables ({% extends template_var %}) but a refactor # will be needed to support that use-case with multiple offline contexts. context = Context() if original is not None: context.template = original compiled_parent = extendsnode.get_parent(context) parent_nodelist = compiled_parent.nodelist # If the parent template has an ExtendsNode it is not the root. for node in parent_nodelist: # The ExtendsNode has to be the first non-text node. if not isinstance(node, TextNode): if isinstance(node, ExtendsNode): return handle_extendsnode(node, block_context, original) break # Add blocks of the root template to block context. blocks = dict((n.name, n) for n in parent_nodelist.get_nodes_by_type(BlockNode)) block_context.add_blocks(blocks) block_stack = [] new_nodelist = remove_block_nodes(parent_nodelist, block_stack, block_context) return new_nodelist
def handle_extendsnode(extendsnode, block_context=None): """Create a copy of Node tree of a derived template replacing all blocks tags with the nodes of appropriate blocks. Also handles {{ block.super }} tags. """ if block_context is None: block_context = BlockContext() blocks = dict((n.name, n) for n in extendsnode.nodelist.get_nodes_by_type(BlockNode)) block_context.add_blocks(blocks) context = Context(settings.COMPRESS_OFFLINE_CONTEXT) compiled_parent = extendsnode.get_parent(context) parent_nodelist = compiled_parent.nodelist # If the parent template has an ExtendsNode it is not the root. for node in parent_nodelist: # The ExtendsNode has to be the first non-text node. if not isinstance(node, TextNode): if isinstance(node, ExtendsNode): return handle_extendsnode(node, block_context) break # Add blocks of the root template to block context. blocks = dict((n.name, n) for n in parent_nodelist.get_nodes_by_type(BlockNode)) block_context.add_blocks(blocks) block_stack = [] new_nodelist = remove_block_nodes(parent_nodelist, block_stack, block_context) return new_nodelist
def handle_extendsnode(extendsnode, block_context=None): """Create a copy of Node tree of a derived template replacing all blocks tags with the nodes of appropriate blocks. Also handles {{ block.super }} tags. """ if block_context is None: block_context = BlockContext() blocks = dict( (n.name, n) for n in extendsnode.nodelist.get_nodes_by_type(BlockNode)) block_context.add_blocks(blocks) context = Context(settings.COMPRESS_OFFLINE_CONTEXT) compiled_parent = extendsnode.get_parent(context) parent_nodelist = compiled_parent.nodelist # If the parent template has an ExtendsNode it is not the root. for node in parent_nodelist: # The ExtendsNode has to be the first non-text node. if not isinstance(node, TextNode): if isinstance(node, ExtendsNode): return handle_extendsnode(node, block_context) break # Add blocks of the root template to block context. blocks = dict( (n.name, n) for n in parent_nodelist.get_nodes_by_type(BlockNode)) block_context.add_blocks(blocks) block_stack = [] new_nodelist = remove_block_nodes(parent_nodelist, block_stack, block_context) return new_nodelist
def resolve_blocks(template, context, blocks=None): '''Get all the blocks from this template, accounting for 'extends' tags''' if blocks is None: blocks = BlockContext() # If it's just the name, resolve into template if isinstance(template, str): template = get_template(template) # Add this templates blocks as the first local_blocks = dict( (block.name, block) for block in template.nodelist.get_nodes_by_type(BlockNode) ) blocks.add_blocks(local_blocks) # Do we extend a parent template? extends = template.nodelist.get_nodes_by_type(ExtendsNode) if extends: # Can only have one extends in a template extends_node = extends[0] # Get the parent, and recurse parent_template = extends_node.get_parent(context) resolve_blocks(parent_template, context, blocks) return blocks
def resolve_blocks(template, context, blocks=None): '''Get all the blocks from this template, accounting for 'extends' tags''' if blocks is None: blocks = BlockContext() # If it's just the name, resolve into template if isinstance(template, str): template = get_template(template) # Add this templates blocks as the first local_blocks = dict( (block.name, block) for block in template.nodelist.get_nodes_by_type(BlockNode)) blocks.add_blocks(local_blocks) # Do we extend a parent template? extends = template.nodelist.get_nodes_by_type(ExtendsNode) if extends: # Can only have one extends in a template extends_node = extends[0] # Get the parent, and recurse parent_template = extends_node.get_parent(context) resolve_blocks(parent_template, context, blocks) return blocks
def test_repr(self): block_context = BlockContext() block_context.add_blocks({"content": BlockNode("content", [])}) self.assertEqual( repr(block_context), "<BlockContext: blocks=defaultdict(<class 'list'>, " "{'content': [<Block Node: content. Contents: []>]})>", )
def get_block_context(self, form_template, blocks): block_context = BlockContext() # Add the block nodes from this node to the block context. block_context.add_blocks(blocks) # Add the template's nodes too if it is the root template. for node in form_template.nodelist: # The ExtendsNode has to be the first non-text node. if not isinstance(node, template.TextNode): if not isinstance(node, ExtendsNode): blocks = dict([(n.name, n) for n in form_template.nodelist\ .get_nodes_by_type(BlockNode)]) block_context.add_blocks(blocks) break return block_context
def handle_extendsnode(extendsnode, block_context=None, original=None): """Create a copy of Node tree of a derived template replacing all blocks tags with the nodes of appropriate blocks. Also handles {{ block.super }} tags. """ if block_context is None: block_context = BlockContext() blocks = dict( (n.name, n) for n in extendsnode.nodelist.get_nodes_by_type(BlockNode)) block_context.add_blocks(blocks) # Note: we pass an empty context when we find the parent, this breaks # inheritance using variables ({% extends template_var %}) but a refactor # will be needed to support that use-case with multiple offline contexts. context = Context() if original is not None: context.template = original compiled_parent = extendsnode.get_parent(context) parent_nodelist = compiled_parent.nodelist # If the parent template has an ExtendsNode it is not the root. for node in parent_nodelist: # The ExtendsNode has to be the first non-text node. if not isinstance(node, TextNode): if isinstance(node, ExtendsNode): return handle_extendsnode(node, block_context, original) break # Add blocks of the root template to block context. blocks = dict( (n.name, n) for n in parent_nodelist.get_nodes_by_type(BlockNode)) block_context.add_blocks(blocks) block_stack = [] new_nodelist = remove_block_nodes(parent_nodelist, block_stack, block_context) return new_nodelist
def reuse(context, block_list, **kwargs): ''' Allow reuse of a block within a template. {% reuse '_myblock' foo=bar %} If passed a list of block names, will use the first that matches: {% reuse list_of_block_names .... %} ''' try: block_context = context.render_context[BLOCK_CONTEXT_KEY] except KeyError: block_context = BlockContext() blocks = { n.name: n for n in context.template.nodelist.get_nodes_by_type(BlockNode) } block_context.add_blocks(blocks) if not isinstance(block_list, (list, tuple)): block_list = [block_list] for name in block_list: block = block_context.get_block(name) if block is not None: break if block is None: return '' context.update(kwargs) try: return block.render(context) finally: context.pop()