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 child_nodelists = ('nodelist_main', 'nodelist_empty',)
14 def __init__(self, name, references=None, as_var=None, nodelist_main=None, nodelist_empty=None):
17 self.references = references
19 if nodelist_main is None:
20 self.nodelist_main = template.NodeList()
22 self.nodelist_main = nodelist_main
24 if nodelist_empty is None:
25 self.nodelist_empty = template.NodeList()
27 self.nodelist_empty = nodelist_empty
29 def render(self, context):
30 content = settings.TEMPLATE_STRING_IF_INVALID
32 container_content = self.get_container_content(context)
34 if self.nodelist_main is None:
36 if container_content and self.as_var:
37 context[self.as_var] = container_content
39 return container_content
42 if self.as_var is None:
43 self.as_var = self.name
47 context[self.as_var] = container_content
48 nodelist = template.NodeList()
49 for node in self.nodelist_main:
50 nodelist.append(node.render(context))
52 return nodelist.render(context)
54 if self.nodelist_empty is not None:
55 return self.nodelist_empty.render(context)
59 def get_container_content(self, context):
60 page = context['page']
63 contentreference = page.contentreferences.get(name__exact=self.name, content_type=self.references)
64 content = contentreference.content
65 except ObjectDoesNotExist:
69 contentlet = page.contentlets.get(name__exact=self.name)
70 if contentlet.dynamic:
72 content = mark_safe(template.Template(contentlet.content, name=contentlet.name).render(context))
73 except template.TemplateSyntaxError, error:
75 content = ('[Error parsing contentlet \'%s\': %s]' % (self.name, error))
77 content = contentlet.content
78 except ObjectDoesNotExist:
83 def do_container(parser, token):
85 {% container <name> [[references <type>] as <variable>] %}
86 {% blockcontainer <name> [[references <type>] as <variable>] %} [ {% empty %} ] {% endblockcontainer %}
88 params = token.split_contents()
91 name = params[1].strip('"')
95 remaining_tokens = params[2:]
96 while remaining_tokens:
97 option_token = remaining_tokens.pop(0)
98 if option_token == 'references':
100 app_label, model = remaining_tokens.pop(0).strip('"').split('.')
101 references = ContentType.objects.get(app_label=app_label, model=model)
103 raise template.TemplateSyntaxError('"%s" template tag option "references" requires an argument specifying a content type' % tag)
105 raise template.TemplateSyntaxError('"%s" template tag option "references" requires an argument of the form app_label.model (see django.contrib.contenttypes)' % tag)
106 except ObjectDoesNotExist:
107 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)
108 elif option_token == 'as':
110 as_var = remaining_tokens.pop(0)
112 raise template.TemplateSyntaxError('"%s" template tag option "as" requires an argument specifying a variable name' % tag)
113 if references and not as_var:
114 raise template.TemplateSyntaxError('"%s" template tags using "references" option require additional use of the "as" option specifying a variable name' % tag)
115 if tag == 'container':
116 return ContainerNode(name, references, as_var)
118 nodelist_main = parser.parse(('empty','endblockcontainer',))
119 token = parser.next_token()
121 if token.contents == 'empty':
122 nodelist_empty = parser.parse(('endblockcontainer',))
123 parser.delete_first_token()
125 nodelist_empty = None
126 return ContainerNode(name, references, as_var, nodelist_main, nodelist_empty)
129 raise template.TemplateSyntaxError('"%s" template tag provided without arguments (at least one required)' % tag)
132 register.tag('container', do_container)
133 register.tag('blockcontainer', do_container)