Renamed navigation to shipherd.
[philo.git] / contrib / shipherd / templatetags / shipherd.py
1 from django import template
2 from django.conf import settings
3 from django.utils.safestring import mark_safe
4 from philo.contrib.shipherd.models import Navigation
5 from mptt.templatetags.mptt_tags import RecurseTreeNode, cache_tree_children
6
7
8 register = template.Library()
9
10
11 class RecurseNavigationNode(RecurseTreeNode):
12         def __init__(self, template_nodes, instance_var):
13                 self.template_nodes = template_nodes
14                 self.instance_var = instance_var
15         
16         def _render_node(self, context, node, request):
17                 bits = []
18                 context.push()
19                 for child in node.get_children():
20                         context['node'] = child
21                         bits.append(self._render_node(context, child, request))
22                 context['node'] = node
23                 context['children'] = mark_safe(u''.join(bits))
24                 context['active'] = node.is_active(request)
25                 rendered = self.template_nodes.render(context)
26                 context.pop()
27                 return rendered
28         
29         def render(self, context):
30                 try:
31                         request = context['request']
32                 except KeyError:
33                         return ''
34                 
35                 instance = self.instance_var.resolve(context)
36                 roots = cache_tree_children(Navigation.objects.closest_navigation(instance))
37                 bits = [self._render_node(context, node, request) for node in roots]
38                 return ''.join(bits)
39
40
41 @register.tag
42 def recursenavigation(parser, token):
43         """
44         Based on django-mptt's recursetree templatetag. In addition to {{ node }} and {{ children }},
45         sets {{ active }} in the context.
46         
47         Note that the tag takes one variable, navigation, which is a Navigation instance.
48         
49         Usage:
50                 <ul>
51                         {% recursenavigation navigation %}
52                                 <li{% if active %} class='active'{% endif %}>
53                                         {{ node.name }}
54                                         {% if not node.is_leaf_node %}
55                                                 <ul>
56                                                         {{ children }}
57                                                 </ul>
58                                         {% endif %}
59                                 </li>
60                         {% endrecursenavigation %}
61                 </ul>
62         """
63         bits = token.contents.split()
64         if len(bits) != 2:
65                 raise template.TemplateSyntaxError(_('%s tag requires an instance') % bits[0])
66         
67         instance_var = template.Variable(bits[1])
68         
69         template_nodes = parser.parse(('endrecursenavigation',))
70         parser.delete_first_token()
71         
72         return RecurseNavigationNode(template_nodes, instance_var)