1 from django import template
2 from django.conf import settings
3 from django.contrib.contenttypes.models import ContentType
4 from django.core.exceptions import ObjectDoesNotExist
5 from django.utils.safestring import SafeUnicode, mark_safe
8 register = template.Library()
11 class ContainerNode(template.Node):
12 def __init__(self, name, references=None, as_var=None):
15 self.references = references
17 def render(self, context):
18 content = settings.TEMPLATE_STRING_IF_INVALID
20 container_content = self.get_container_content(context)
22 container_content = None
25 context[self.as_var] = container_content
28 if not container_content:
31 return container_content
33 def get_container_content(self, context):
34 page = context['page']
36 # Then it's a content reference.
38 contentreference = page.contentreferences.get(name__exact=self.name, content_type=self.references)
39 content = contentreference.content
40 except ObjectDoesNotExist:
43 # Otherwise it's a contentlet.
45 contentlet = page.contentlets.get(name__exact=self.name)
46 if '{%' in contentlet.content or '{{' in contentlet.content:
48 content = template.Template(contentlet.content, name=contentlet.name).render(context)
49 except template.TemplateSyntaxError, error:
51 content = ('[Error parsing contentlet \'%s\': %s]' % (self.name, error))
53 content = settings.TEMPLATE_STRING_IF_INVALID
55 content = contentlet.content
56 except ObjectDoesNotExist:
57 content = settings.TEMPLATE_STRING_IF_INVALID
58 content = mark_safe(content)
62 def do_container(parser, token):
64 {% container <name> [[references <type>] as <variable>] %}
66 params = token.split_contents()
69 name = params[1].strip('"')
73 remaining_tokens = params[2:]
74 while remaining_tokens:
75 option_token = remaining_tokens.pop(0)
76 if option_token == 'references':
78 app_label, model = remaining_tokens.pop(0).strip('"').split('.')
79 references = ContentType.objects.get(app_label=app_label, model=model)
81 raise template.TemplateSyntaxError('"%s" template tag option "references" requires an argument specifying a content type' % tag)
83 raise template.TemplateSyntaxError('"%s" template tag option "references" requires an argument of the form app_label.model (see django.contrib.contenttypes)' % tag)
84 except ObjectDoesNotExist:
85 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)
86 elif option_token == 'as':
88 as_var = remaining_tokens.pop(0)
90 raise template.TemplateSyntaxError('"%s" template tag option "as" requires an argument specifying a variable name' % tag)
91 if references and not as_var:
92 raise template.TemplateSyntaxError('"%s" template tags using "references" option require additional use of the "as" option specifying a variable name' % tag)
93 return ContainerNode(name, references, as_var)
96 raise template.TemplateSyntaxError('"%s" template tag provided without arguments (at least one required)' % tag)
99 register.tag('container', do_container)