def _scan_placeholders(nodelist, current_block=None, ignore_blocks=None):
from cms.templatetags.cms_tags import Placeholder
placeholders = []
if ignore_blocks is None:
# List of BlockNode instances to ignore.
# This is important to avoid processing overriden block nodes.
ignore_blocks = []
for node in nodelist:
# check if this is a placeholder first
if isinstance(node, Placeholder):
placeholders.append(node.get_name())
elif isinstance(node, IncludeNode):
# if there's an error in the to-be-included template, node.template becomes None
if node.template:
# Check if it quacks like a template object, if not
# presume is a template path and get the object out of it
if not callable(getattr(node.template, 'render', None)):
# If it's a variable there is no way to expand it at this stage so we
# need to skip it
if isinstance(node.template.var, Variable):
continue
else:
template = get_template(node.template.var)
else:
template = node.template
placeholders += _scan_placeholders(_get_nodelist(template), current_block)
# handle {% extends ... %} tags
elif isinstance(node, ExtendsNode):
placeholders += _extend_nodelist(node)
# in block nodes we have to scan for super blocks
elif isinstance(node, VariableNode) and current_block:
if node.filter_expression.token == 'block.super':
if not hasattr(current_block.super, 'nodelist'):
raise TemplateSyntaxError("Cannot render block.super for blocks without a parent.")
placeholders += _scan_placeholders(_get_nodelist(current_block.super), current_block.super)
# ignore nested blocks which are already handled
elif isinstance(node, BlockNode) and node.name in ignore_blocks:
continue
# if the node has the newly introduced 'child_nodelists' attribute, scan
# those attributes for nodelists and recurse them
elif hasattr(node, 'child_nodelists'):
for nodelist_name in node.child_nodelists:
if hasattr(node, nodelist_name):
subnodelist = getattr(node, nodelist_name)
if isinstance(subnodelist, NodeList):
if isinstance(node, BlockNode):
current_block = node
placeholders += _scan_placeholders(subnodelist, current_block, ignore_blocks)
# else just scan the node for nodelist instance attributes
else:
for attr in dir(node):
obj = getattr(node, attr)
if isinstance(obj, NodeList):
if isinstance(node, BlockNode):
current_block = node
placeholders += _scan_placeholders(obj, current_block, ignore_blocks)
return placeholders
评论列表
文章目录