Initial implementation of node_url templatetag.
[philo.git] / templatetags / nodes.py
1 from django import template
2 from django.conf import settings
3 from django.contrib.sites.models import Site
4
5
6 register = template.Library()
7
8
9 class NodeURLNode(template.Node):
10         def __init__(self, node, with_obj, as_var):
11                 if node is not None:
12                         self.node = template.Variable(node)
13                 else:
14                         self.node = None
15                 
16                 if with_obj is not None:
17                         self.with_obj = template.Variable(with_obj)
18                 else:
19                         self.with_obj = None
20                 
21                 self.as_var = as_var
22         
23         def render(self, context):
24                 try:
25                         if self.node:
26                                 node = self.node.resolve(context)
27                         else:
28                                 node = context['node']
29                         current_site = Site.objects.get_current()
30                         if node.has_ancestor(current_site.root_node):
31                                 url = node.get_path(root=current_site.root_node)
32                                 if self.with_obj:
33                                         with_obj = self.with_obj.resolve(context)
34                                         url += node.view.get_subpath(with_obj)
35                         else:
36                                 return settings.TEMPLATE_STRING_IF_INVALID
37                         
38                         if self.as_var:
39                                 context[self.as_var] = url
40                                 return settings.TEMPLATE_STRING_IF_INVALID
41                         else:
42                                 return url
43                 except:
44                         return settings.TEMPLATE_STRING_IF_INVALID
45
46
47 @register.tag(name='node_url')
48 def do_node_url(parser, token):
49         """
50         {% node_url [<node>] [with <obj>] [as <var>] %}
51         """
52         params = token.split_contents()
53         tag = params[0]
54         
55         if len(params) <= 6:
56                 node = None
57                 with_obj = None
58                 as_var = None
59                 remaining_tokens = params[1:]
60                 while remaining_tokens:
61                         option_token = remaining_tokens.pop(0)
62                         if option_token == 'with':
63                                 try:
64                                         with_obj = remaining_tokens.pop(0)
65                                 except IndexError:
66                                         raise template.TemplateSyntaxError('"%s" template tag option "with" requires an argument specifying an object handled by the view on the node' % tag)
67                         elif option_token == 'as':
68                                 try:
69                                         as_var = remaining_tokens.pop(0)
70                                 except IndexError:
71                                         raise template.TemplateSyntaxError('"%s" template tag option "as" requires an argument specifying a variable name' % tag)
72                         else: # node
73                                 node = option_token
74                 return NodeURLNode(node=node, with_obj=with_obj, as_var=as_var)
75         else:
76                 raise template.TemplateSyntaxError('"%s" template tag cannot accept more than five arguments' % tag)