2 The container template tags are automatically included as builtins if :mod:`philo` is an installed app.
4 .. templatetag:: container
9 If a template using this tag is used to render a :class:`.Page`, that :class:`.Page` will have associated content which can be set in the admin interface. If a content type is referenced, then a :class:`.ContentReference` object will be created; otherwise, a :class:`.Contentlet` object will be created.
13 {% container <name> [[references <app_label>.<model_name>] as <variable>] %}
17 from django import template
18 from django.conf import settings
19 from django.contrib.contenttypes.models import ContentType
20 from django.core.exceptions import ObjectDoesNotExist
21 from django.utils.safestring import SafeUnicode, mark_safe
24 register = template.Library()
27 class ContainerNode(template.Node):
28 def __init__(self, name, references=None, as_var=None):
31 self.references = references
33 def render(self, context):
34 content = settings.TEMPLATE_STRING_IF_INVALID
36 container_content = self.get_container_content(context)
38 container_content = None
41 context[self.as_var] = container_content
44 if not container_content:
47 return container_content
49 def get_container_content(self, context):
50 page = context['page']
52 # Then it's a content reference.
54 contentreference = page.contentreferences.get(name__exact=self.name, content_type=self.references)
55 content = contentreference.content
56 except ObjectDoesNotExist:
59 # Otherwise it's a contentlet.
61 contentlet = page.contentlets.get(name__exact=self.name)
62 if '{%' in contentlet.content or '{{' in contentlet.content:
64 content = template.Template(contentlet.content, name=contentlet.name).render(context)
65 except template.TemplateSyntaxError, error:
67 content = ('[Error parsing contentlet \'%s\': %s]' % (self.name, error))
69 content = settings.TEMPLATE_STRING_IF_INVALID
71 content = contentlet.content
72 except ObjectDoesNotExist:
73 content = settings.TEMPLATE_STRING_IF_INVALID
74 content = mark_safe(content)
78 def do_container(parser, token):
80 {% container <name> [[references <app_label>.<model_name>] as <variable>] %}
83 params = token.split_contents()
86 name = params[1].strip('"')
90 remaining_tokens = params[2:]
91 while remaining_tokens:
92 option_token = remaining_tokens.pop(0)
93 if option_token == 'references':
95 app_label, model = remaining_tokens.pop(0).strip('"').split('.')
96 references = ContentType.objects.get(app_label=app_label, model=model)
98 raise template.TemplateSyntaxError('"%s" template tag option "references" requires an argument specifying a content type' % tag)
100 raise template.TemplateSyntaxError('"%s" template tag option "references" requires an argument of the form app_label.model (see django.contrib.contenttypes)' % tag)
101 except ObjectDoesNotExist:
102 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)
103 elif option_token == 'as':
105 as_var = remaining_tokens.pop(0)
107 raise template.TemplateSyntaxError('"%s" template tag option "as" requires an argument specifying a variable name' % tag)
108 if references and not as_var:
109 raise template.TemplateSyntaxError('"%s" template tags using "references" option require additional use of the "as" option specifying a variable name' % tag)
110 return ContainerNode(name, references, as_var)
113 raise template.TemplateSyntaxError('"%s" template tag provided without arguments (at least one required)' % tag)
116 register.tag('container', do_container)