Added is_active method to Navigation class. Replaced the get_navigation and is_active...
[philo.git] / contrib / navigation / templatetags / navigation.py
index 11fdb44..4510f15 100644 (file)
@@ -1,29 +1,72 @@
 from django import template
 from django.conf import settings
+from django.utils.safestring import mark_safe
 from philo.contrib.navigation.models import Navigation
+from mptt.templatetags.mptt_tags import RecurseTreeNode, cache_tree_children
 
 
 register = template.Library()
 
 
-@register.filter
-def get_navigation(node):
-       return Navigation.objects.closest_navigation(node)
+class RecurseNavigationNode(RecurseTreeNode):
+       def __init__(self, template_nodes, instance_var):
+               self.template_nodes = template_nodes
+               self.instance_var = instance_var
+       
+       def _render_node(self, context, node, request):
+               bits = []
+               context.push()
+               for child in node.get_children():
+                       context['node'] = child
+                       bits.append(self._render_node(context, child, request))
+               context['node'] = node
+               context['children'] = mark_safe(u''.join(bits))
+               context['active'] = node.is_active(request)
+               rendered = self.template_nodes.render(context)
+               context.pop()
+               return rendered
+       
+       def render(self, context):
+               try:
+                       request = context['request']
+               except KeyError:
+                       return ''
+               
+               instance = self.instance_var.resolve(context)
+               roots = cache_tree_children(Navigation.objects.closest_navigation(instance))
+               bits = [self._render_node(context, node, request) for node in roots]
+               return ''.join(bits)
 
-@register.filter
-def is_active(navigation, request):
+
+@register.tag
+def recursenavigation(parser, token):
        """
-       Returns true if the navigation is considered `active`.
+       Based on django-mptt's recursetree templatetag. In addition to {{ node }} and {{ children }},
+       sets {{ active }} in the context.
+       
+       Note that the tag takes one variable, navigation, which is a Navigation instance.
        
-       But what does "active" mean? Should this be defined on the model instead, perhaps?
+       Usage:
+               <ul>
+                       {% recursenavigation navigation %}
+                               <li{% if active %} class='active'{% endif %}>
+                                       {{ node.name }}
+                                       {% if not node.is_leaf_node %}
+                                               <ul>
+                                                       {{ children }}
+                                               </ul>
+                                       {% endif %}
+                               </li>
+                       {% endrecursenavigation %}
+               </ul>
        """
-       try:
-               if navigation.target_node == request.node:
-                       if request.path == navigation.target_url:
-                               return True
-                       return False
-               if navigation.target_url in request.path:
-                       return True
-       except:
-               pass
-       return False
\ No newline at end of file
+       bits = token.contents.split()
+       if len(bits) != 2:
+               raise template.TemplateSyntaxError(_('%s tag requires an instance') % bits[0])
+       
+       instance_var = template.Variable(bits[1])
+       
+       template_nodes = parser.parse(('endrecursenavigation',))
+       parser.delete_first_token()
+       
+       return RecurseNavigationNode(template_nodes, instance_var)
\ No newline at end of file