from philo.utils import nodelist_crawl
-embed_re = re.compile("{% embed (?P<app_label>\w+)\.(?P<model>\w+) (?P<pk>)\w+ %}")
-
-
class Embed(models.Model):
embedder_content_type = models.ForeignKey(ContentType, related_name="embedder_related")
embedder_object_id = models.PositiveIntegerField()
for field in embedder._meta.fields:
if isinstance(field, EmbedField):
attr = getattr(embedder, field.attname)
- setattr(embedder, field.attname, attr.replace(self.get_embed_tag(), ''))
+ setattr(embedder, field.attname, self.embed_re.sub('', attr))
embedder.save()
- def get_embed_tag(self):
- """Convenience function to construct the embed tag that would create this instance."""
- ct = self.embedded_content_type
- return "{%% embed %s.%s %s %%}" % (ct.app_label, ct.model, self.embedded_object_id)
+ def get_embed_re(self):
+ """Convenience function to return a compiled regular expression to find embed tags that would create this instance."""
+ if not hasattr(self, '_embed_re'):
+ ct = self.embedded_content_type
+ self._embed_re = re.compile("{%% ?embed %s.%s %s( .*?)? ?%%}" % (ct.app_label, ct.model, self.embedded_object_id))
+ return self._embed_re
+ embed_re = property(get_embed_re)
class Meta:
app_label = 'penfield'
class EmbedNode(template.Node):
- def __init__(self, content_type, varname, object_pk=None, template_name=None):
+ def __init__(self, content_type, varname, object_pk=None, template_name=None, kwargs=None):
assert template_name is not None or object_pk is not None
self.content_type = content_type
self.varname = varname
+ kwargs = kwargs or {}
+ for k, v in kwargs.items():
+ kwargs[k] = template.Variable(v)
+ self.kwargs = kwargs
+
if object_pk is not None:
self.object_pk = object_pk
try:
context.push()
context['embedded'] = self.instance
+ for k, v in self.kwargs.items():
+ self.kwargs[k] = v.resolve(context)
+ context.update(self.kwargs)
t_rendered = t.render(context)
context.pop()
return t_rendered
The {% embed %} tag can be used in three ways:
{% embed as <varname> %} :: This sets which variable will be used to track embedding template names for the current context. Default: "embed"
{% embed <app_label>.<model_name> with <template> %} :: Sets which template will be used to render a particular model.
- {% embed <app_label>.<model_name> <object_pk> %} :: Embeds the instance specified by the given parameters in the document with the previously-specified template.
+ {% embed <app_label>.<model_name> <object_pk> [<argname>=<value> ...]%} :: Embeds the instance specified by the given parameters in the document with the previously-specified template. Any kwargs provided will be passed into the context of the template.
"""
args = token.split_contents()
tag = args[0]
if len(args) < 2:
raise template.TemplateSyntaxError('"%s" template tag must have at least three arguments.' % tag)
- elif len(args) > 4:
- raise template.TemplateSyntaxError('"%s" template tag may have no more than four arguments.' % tag)
+ elif len(args) == 3 and args[1] == "as":
+ parser._embedNodeVarName = args[2]
+ return template.defaulttags.CommentNode()
else:
- if len(args) == 3 and args[1] == "as":
- parser._embedNodeVarName = args[2]
- return template.defaulttags.CommentNode()
-
if '.' not in args[1]:
raise template.TemplateSyntaxError('"%s" template tag expects the first argument to be of the form app_label.model' % tag)
except ContentType.DoesNotExist:
raise template.TemplateSyntaxError('"%s" template tag option "references" requires an argument of the form app_label.model which refers to an installed content type (see django.contrib.contenttypes)' % tag)
- if len(args) == 3:
-
- return EmbedNode(ct, object_pk=args[2], varname=getattr(parser, '_embedNodeVarName', 'embed'))
- else:
- # 3 args
- if args[2] != "with":
- raise template.TemplateSyntaxError('"%s" template tag requires the second of three arguments to be "with"' % tag)
+ if args[2] == "with":
+ if len(args) > 4:
+ raise template.TemplateSyntaxError('"%s" template tag may have no more than four arguments.' % tag)
if args[3][0] not in ['"', "'"] and args[3][-1] not in ['"', "'"]:
raise template.TemplateSyntaxError('"%s" template tag expects the template name to be in quotes.' % tag)
template_name = args[3].strip('"\'')
return EmbedNode(ct, template_name=template_name, varname=getattr(parser, '_embedNodeVarName', 'embed'))
+ object_pk = args[2]
+ varname = getattr(parser, '_embedNodeVarName', 'embed')
+
+ remaining_args = args[3:]
+ kwargs = {}
+ for arg in remaining_args:
+ if '=' not in arg:
+ raise template.TemplateSyntaxError("Invalid keyword argument for '%s' template tag: %s" % (tag, arg))
+ k, v = arg.split('=')
+ kwargs[k] = v
+
+ return EmbedNode(ct, object_pk=object_pk, varname=varname, kwargs=kwargs)
register.tag('embed', do_embed)
\ No newline at end of file