old_extends_node_init = ExtendsNode.__init__
-def get_embed_dict(nodelist):
+def get_embed_dict(embed_list, context):
embeds = {}
- for n in nodelist.get_nodes_by_type(ConstantEmbedNode):
- if n.content_type not in embeds:
- embeds[n.content_type] = [n]
+ for e in embed_list:
+ ct = e.get_content_type(context)
+ if ct is None:
+ # Then the embed doesn't exist for this context.
+ continue
+ if ct not in embeds:
+ embeds[ct] = [e]
else:
- embeds[n.content_type].append(n)
+ embeds[ct].append(e)
return embeds
def extends_node_init(self, nodelist, *args, **kwargs):
- self.embeds = get_embed_dict(nodelist)
+ self.embed_list = nodelist.get_nodes_by_type(ConstantEmbedNode)
old_extends_node_init(self, nodelist, *args, **kwargs)
def render_extends_node(self, context):
compiled_parent = self.get_parent(context)
+ embeds = get_embed_dict(self.embed_list, context)
if BLOCK_CONTEXT_KEY not in context.render_context:
context.render_context[BLOCK_CONTEXT_KEY] = BlockContext()
# Add the block nodes from this node to the block context
# Do the equivalent for embed nodes
block_context.add_blocks(self.blocks)
- embed_context.add_embeds(self.embeds)
+ embed_context.add_embeds(embeds)
# 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.
if not isinstance(node, ExtendsNode):
blocks = dict([(n.name, n) for n in compiled_parent.nodelist.get_nodes_by_type(BlockNode)])
block_context.add_blocks(blocks)
- embeds = get_embed_dict(compiled_parent.nodelist)
+ embeds = get_embed_dict(compiled_parent.nodelist.get_nodes_by_type(ConstantEmbedNode), context)
embed_context.add_embeds(embeds)
break
-
+
+ # Explicitly render all direct embed children of this node.
+ if self.embed_list:
+ for node in self.nodelist:
+ if isinstance(node, ConstantEmbedNode):
+ node.render(context)
+
# Call Template._render explicitly so the parser context stays
# the same.
return compiled_parent._render(context)
self.template = None
def compile_instance(self, object_pk):
- self.object_pk = object_pk
model = self.content_type.model_class()
try:
return model.objects.get(pk=object_pk)
try:
return template.loader.get_template(template_name)
except template.TemplateDoesNotExist:
- if not hasattr(self, 'template_name') and settings.TEMPLATE_DEBUG:
+ if hasattr(self, 'template') and settings.TEMPLATE_DEBUG:
# Then it's a constant node.
raise
return False
try:
t = context.render_context[EMBED_CONTEXT_KEY].get_embed_template(self, context)
except (KeyError, IndexError):
- if settings.TEMPLATE_DEBUG:
- raise
+ self.mark_rendered_for(context)
return settings.TEMPLATE_STRING_IF_INVALID
context.push()
context['embedded'] = instance
- kwargs = {}
for k, v in self.kwargs.items():
- kwargs[k] = v.resolve(context)
- context.update(kwargs)
+ context[k] = v.resolve(context)
t_rendered = t.render(context)
context.pop()
self.mark_rendered_for(context)
self.object_pk = object_pk
else:
self.object_pk = None
- self.instance = None
if template_name is not None:
self.template_name = template_name
else:
self.template_name = None
- self.template = None
def get_instance(self, context):
if self.object_pk is None:
return self.instance.resolve(context)
def get_content_type(self, context):
- return ContentType.objects.get_for_model(self.get_instance(context))
+ instance = self.get_instance(context)
+ if not instance:
+ return None
+ return ContentType.objects.get_for_model(instance)
def get_embedded(self):
setattr(ConstantEmbedNode, LOADED_TEMPLATE_ATTR, property(get_embedded))
-def get_content_type(bit):
+def parse_content_type(bit, tagname):
try:
app_label, model = bit.split('.')
except ValueError:
- raise template.TemplateSyntaxError('"%s" template tag expects the first argument to be of the form app_label.model' % tag)
+ raise template.TemplateSyntaxError('"%s" template tag expects the first argument to be of the form app_label.model' % tagname)
try:
ct = ContentType.objects.get(app_label=app_label, model=model)
except ContentType.DoesNotExist:
- raise template.TemplateSyntaxError('"%s" template tag requires an argument of the form app_label.model which refers to an installed content type (see django.contrib.contenttypes)' % tag)
+ raise template.TemplateSyntaxError('"%s" template tag requires an argument of the form app_label.model which refers to an installed content type (see django.contrib.contenttypes)' % tagname)
return ct
raise template.TemplateSyntaxError('"%s" template tag must have at least two arguments.' % tag)
if len(bits) == 3 and bits[-2] == 'with':
- ct = get_content_type(bits[0])
+ ct = parse_content_type(bits[0], tag)
if bits[2][0] in ['"', "'"] and bits[2][0] == bits[2][-1]:
return ConstantEmbedNode(ct, template_name=bits[2])
return InstanceEmbedNode(instance, kwargs)
elif len(bits) > 2:
raise template.TemplateSyntaxError('"%s" template tag expects at most 2 non-keyword arguments when embedding instances.')
- ct = get_content_type(bits[0])
+ ct = parse_content_type(bits[0], tag)
pk = bits[1]
try: