1 from django import template
2 from django.conf import settings
3 from django.utils.safestring import SafeUnicode, mark_safe
4 from django.core.exceptions import ObjectDoesNotExist
5 from django.contrib.contenttypes.models import ContentType
8 register = template.Library()
11 class ContainerNode(template.Node):
12 def __init__(self, name, references=None, as_var=None, nodelist_main=None, nodelist_empty=None):
15 self.references = references
16 self.nodelist_main = nodelist_main
17 self.nodelist_empty = nodelist_empty
19 def render(self, context):
20 content = settings.TEMPLATE_STRING_IF_INVALID
22 container_content = self.get_container_content(context['page'])
24 if self.nodelist_main is None:
25 if container_content and self.as_var:
26 context[self.as_var] = container_content
28 return container_content
31 if self.as_var is None:
32 self.as_var = self.name
34 context[self.as_var] = container_content
35 return nodelist_main.render(context)
37 if nodelist_empty is not None:
38 return nodelist_empty.render(context)
42 def get_container_content(self, page):
45 contentreference = page.contentreferences.get(name__exact=self.name, content_type=self.references)
46 content = contentreference.content
47 except ObjectDoesNotExist:
51 contentlet = page.contentlets.get(name__exact=self.name)
52 if contentlet.dynamic:
54 content = mark_safe(template.Template(contentlet.content, name=contentlet.name).render(context))
55 except template.TemplateSyntaxError, error:
57 content = ('[Error parsing contentlet \'%s\': %s]' % self.name, error)
59 content = contentlet.content
60 except ObjectDoesNotExist:
64 def do_container(parser, token):
66 {% container <name> [[references <type>] as <variable>] %}
67 {% blockcontainer <name> [[references <type>] as <variable>] %} [ {% empty %} ] {% endblockcontainer %}
69 params = token.split_contents()
72 name = params[1].strip('"')
76 remaining_tokens = params[2:]
77 while remaining_tokens:
78 option_token = remaining_tokens.pop(0)
79 if option_token == 'references':
81 app_label, model = remaining_tokens.pop(0).strip('"').split('.')
82 references = ContentType.objects.get(app_label=app_label, model=model)
84 raise template.TemplateSyntaxError('"%s" template tag option "references" requires an argument specifying a content type' % tag)
86 raise template.TemplateSyntaxError('"%s" template tag option "references" requires an argument of the form app_label.model (see django.contrib.contenttypes)' % tag)
87 except ObjectDoesNotExist:
88 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)
89 elif option_token == 'as':
91 as_var = remaining_tokens.pop(0)
93 raise template.TemplateSyntaxError('"%s" template tag option "as" requires an argument specifying a variable name' % tag)
94 if references and not as_var:
95 raise template.TemplateSyntaxError('"%s" template tags using "references" option require additional use of the "as" option specifying a variable name' % tag)
96 if tag == 'container':
97 return ContainerNode(name, references, as_var)
99 nodelist_main = parser.parse(('empty','endblockcontainer',))
100 token = parser.next_token()
102 if token.contents == 'empty':
103 nodelist_empty = parser.parse(('endblockcontainer',))
104 parser.delete_first_token()
106 nodelist_empty = None
107 return BlockContainerNode(name, references, as_var, nodelist_main, nodelist_empty)
110 raise template.TemplateSyntaxError('"%s" template tag provided without arguments (at least one required)' % tag)
111 register.tag('container', do_container)