class ExtendsNode
from django.template.loader_tags import ExtendsNode
Ancestors (MRO)
- builtins.object
- django.template.base.Node
- django.template.loader_tags.ExtendsNode
Attribute | Type | Defined in |
---|---|---|
__dict__ |
getset_descriptor
|
django.template.base.Node |
__weakref__ |
getset_descriptor
|
django.template.base.Node |
Attribute | Value | Defined in |
---|---|---|
child_nodelists |
('nodelist',) |
django.template.base.Node |
context_key |
extends_context |
django.template.loader_tags.ExtendsNode |
must_be_first |
True |
django.template.loader_tags.ExtendsNode |
must_be_first |
False |
django.template.base.Node |
token |
None |
django.template.base.Node |
def __init__(self, nodelist, parent_name, template_dirs=None)
django.template.loader_tags.ExtendsNode
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, nodelist, parent_name, template_dirs=None):
self.nodelist = nodelist
self.parent_name = parent_name
self.template_dirs = template_dirs
self.blocks = {n.name: n for n in nodelist.get_nodes_by_type(BlockNode)}
def __repr__(self)
django.template.loader_tags.ExtendsNode
Return repr(self).
def __repr__(self):
return "<%s: extends %s>" % (self.__class__.__name__, self.parent_name.token)
def find_template(self, template_name, context)
django.template.loader_tags.ExtendsNode
This is a wrapper around engine.find_template(). A history is kept in the render_context attribute between successive extends calls and passed as the skip argument. This enables extends to work recursively without extending the same template twice.
def find_template(self, template_name, context):
"""
This is a wrapper around engine.find_template(). A history is kept in
the render_context attribute between successive extends calls and
passed as the skip argument. This enables extends to work recursively
without extending the same template twice.
"""
history = context.render_context.setdefault(
self.context_key,
[self.origin],
)
template, origin = context.template.engine.find_template(
template_name,
skip=history,
)
history.append(origin)
return template
def get_nodes_by_type(self, nodetype)
django.template.base.Node
Return a list of all nodes (within this node and its nodelist) of the given type
def get_nodes_by_type(self, nodetype):
"""
Return a list of all nodes (within this node and its nodelist)
of the given type
"""
nodes = []
if isinstance(self, nodetype):
nodes.append(self)
for attr in self.child_nodelists:
nodelist = getattr(self, attr, None)
if nodelist:
nodes.extend(nodelist.get_nodes_by_type(nodetype))
return nodes
def get_parent(self, context)
django.template.loader_tags.ExtendsNode
def get_parent(self, context):
parent = self.parent_name.resolve(context)
if not parent:
error_msg = "Invalid template name in 'extends' tag: %r." % parent
if self.parent_name.filters or isinstance(self.parent_name.var, Variable):
error_msg += (
" Got this from the '%s' variable." % self.parent_name.token
)
raise TemplateSyntaxError(error_msg)
if isinstance(parent, Template):
# parent is a django.template.Template
return parent
if isinstance(getattr(parent, "template", None), Template):
# parent is a django.template.backends.django.Template
return parent.template
return self.find_template(parent, context)
def render(self, context)
django.template.loader_tags.ExtendsNode
django.template.loader_tags.ExtendsNode
Return the node rendered as a string.
def render(self, context):
compiled_parent = self.get_parent(context)
if BLOCK_CONTEXT_KEY not in context.render_context:
context.render_context[BLOCK_CONTEXT_KEY] = BlockContext()
block_context = context.render_context[BLOCK_CONTEXT_KEY]
# Add the block nodes from this node to the block context
block_context.add_blocks(self.blocks)
# If this block's parent doesn't have an extends node it is the root,
# and its block nodes also need to be added to the block context.
for node in compiled_parent.nodelist:
# The ExtendsNode has to be the first non-text node.
if not isinstance(node, TextNode):
if not isinstance(node, ExtendsNode):
blocks = {
n.name: n
for n in compiled_parent.nodelist.get_nodes_by_type(BlockNode)
}
block_context.add_blocks(blocks)
break
# Call Template._render explicitly so the parser context stays
# the same.
with context.render_context.push_state(compiled_parent, isolated_context=False):
return compiled_parent._render(context)
django.template.base.Node
Return the node rendered as a string.
def render(self, context):
"""
Return the node rendered as a string.
"""
pass
def render_annotated(self, context)
django.template.base.Node
Render the node. If debug is True and an exception occurs during rendering, the exception is annotated with contextual line information where it occurred in the template. For internal usage this method is preferred over using the render method directly.
def render_annotated(self, context):
"""
Render the node. If debug is True and an exception occurs during
rendering, the exception is annotated with contextual line information
where it occurred in the template. For internal usage this method is
preferred over using the render method directly.
"""
try:
return self.render(context)
except Exception as e:
if context.template.engine.debug:
# Store the actual node that caused the exception.
if not hasattr(e, "_culprit_node"):
e._culprit_node = self
if (
not hasattr(e, "template_debug")
and context.render_context.template.origin == e._culprit_node.origin
):
e.template_debug = (
context.render_context.template.get_exception_info(
e,
e._culprit_node.token,
)
)
raise