Browse Source

Admin nav system.

Rafał Pitoń 11 years ago
parent
commit
846a6fe7b3

+ 130 - 33
misago/admin/hierarchy.py

@@ -1,37 +1,100 @@
+from django.core.urlresolvers import reverse
+
+
 class Node(object):
 class Node(object):
     def __init__(self, link=None, name=None, icon=None):
     def __init__(self, link=None, name=None, icon=None):
+        self.parent = None
         self.link = link
         self.link = link
         self.name = name
         self.name = name
         self.icon = icon
         self.icon = icon
         self._children = []
         self._children = []
         self._children_dict = {}
         self._children_dict = {}
 
 
+    @property
+    def namespace(self):
+        try:
+            return self._resolved_namespace
+        except AttributeError:
+            bits = self.link.split(':')
+            self._resolved_namespace = ':'.join(bits[:-1])
+
+        return self._resolved_namespace
+
     def children(self):
     def children(self):
         return self._children
         return self._children
 
 
-    def add_node(self, node, after=None, before=None):
-        self._children.append(node)
-        self._children_dict[node['link']] = node
+    def children_as_dicts(self):
+        childrens = []
+        for children in self._children:
+            childrens.append({
+                    'link': reverse(children.link),
+                    'namespace': self.namespace,
+                    'name': children.name,
+                    'icon': children.icon,
+                })
+        return childrens
 
 
-    def child(self, node):
+    def add_node(self, node, after=None, before=None):
+        if after:
+            return self.add_node_after(node, after)
+        elif before:
+            return self.add_node_before(node, before)
+        else:
+            node.parent = self
+            self._children.append(node)
+            self._children_dict[node.link] = node
+            return True
+
+    def add_node_after(self, node, after):
+        success = False
+        new_children_list = []
+
+        for children in self._children:
+            new_children_list.append(children)
+            if children.link == after:
+                new_children_list.append(node)
+                success = True
+
+        if success:
+            node.parent = self
+            self._children_dict[node.link] = node
+            self._children = new_children_list
+        return success
+
+    def add_node_before(self, node, before):
+        success = False
+        new_children_list = []
+
+        for children in self._children:
+            if children.link == before:
+                new_children_list.append(node)
+                success = True
+            new_children_list.append(children)
+
+        if success:
+            node.parent = self
+            self._children_dict[node.link] = node
+            self._children = new_children_list
+        return success
+
+    def child(self, namespace):
         try:
         try:
-            return self._children_dict[node]
+            return self._children_dict[namespace]
         except KeyError:
         except KeyError:
             raise ValueError(
             raise ValueError(
-                "Node %s is not a child of node %s" % (node, self.name))
+                "Node %s is not a child of node %s" % (namespace, self.name))
 
 
     def is_root(self):
     def is_root(self):
         return False
         return False
 
 
 
 
-
 class AdminHierarchyBuilder(object):
 class AdminHierarchyBuilder(object):
     def __init__(self):
     def __init__(self):
         self.nodes_record = []
         self.nodes_record = []
         self.nodes_dict = {}
         self.nodes_dict = {}
 
 
     def build_nodes_dict(self):
     def build_nodes_dict(self):
-        nodes_dict = {'misago:admin': Node()}
+        nodes_dict = {'misago:admin': Node(link='misago:admin:index')}
 
 
         iterations = 0
         iterations = 0
         while self.nodes_record:
         while self.nodes_record:
@@ -41,28 +104,38 @@ class AdminHierarchyBuilder(object):
                           "to resolve. Nodes left: %s" % self.nodes_record)
                           "to resolve. Nodes left: %s" % self.nodes_record)
                 raise ValueError(message)
                 raise ValueError(message)
 
 
-            node = self.nodes_record[0]
-            if node['parent'] in nodes_dict:
-                parent = nodes_dict[node['parent']]
-                node_obj = Node(link=node['link'],
-                                name=node['name'],
-                                icon=node['icon'])
-                if node['after']:
-                    parent.add_node(node, after=node['after'])
-                elif node['before']:
-                    parent.add_node(node, before=node['before'])
-                else:
-                    parent.add_node(node)
-
-                namespace = ':'.join(node['link'].split(':')[:-1])
-                if namespace not in nodes_dict:
-                    nodes_dict[namespace] = node
-                self.nodes_record = self.nodes_record[1:]
+            for index, node in enumerate(self.nodes_record):
+                if node['parent'] in nodes_dict:
+                    node_obj = Node(link=node['link'],
+                                    name=node['name'],
+                                    icon=node['icon'])
+
+                    parent = nodes_dict[node['parent']]
+                    if node['after']:
+                        node_added = parent.add_node(node_obj,
+                                                     after=node['after'])
+                    elif node['before']:
+                        node_added = parent.add_node(node_obj,
+                                                     before=node['before'])
+                    else:
+                        node_added = parent.add_node(node_obj)
+
+                    if node_added:
+                        if node['namespace']:
+                            namespace = '%s:%s' % (node['parent'], node['namespace'])
+                        else:
+                            namespace = node['parent']
+
+                        if namespace not in nodes_dict:
+                            nodes_dict[namespace] = node_obj
+
+                        del self.nodes_record[index]
+                        break
 
 
         return nodes_dict
         return nodes_dict
 
 
     def add_node(self, parent='misago:admin', after=None, before=None,
     def add_node(self, parent='misago:admin', after=None, before=None,
-                 link=None, name=None, icon=None):
+                 namespace=None, link=None, name=None, icon=None):
         if self.nodes_dict:
         if self.nodes_dict:
             raise ValueError("Misago admin site has already been "
             raise ValueError("Misago admin site has already been "
                              "initialized. You can't add new nodes to it.")
                              "initialized. You can't add new nodes to it.")
@@ -72,6 +145,7 @@ class AdminHierarchyBuilder(object):
 
 
         self.nodes_record.append({
         self.nodes_record.append({
                 'parent': parent,
                 'parent': parent,
+                'namespace': namespace,
                 'after': after,
                 'after': after,
                 'before': before,
                 'before': before,
                 'link': link,
                 'link': link,
@@ -79,16 +153,39 @@ class AdminHierarchyBuilder(object):
                 'icon': icon,
                 'icon': icon,
             })
             })
 
 
-    def is_root(self):
-        return True
-
-    def children(self, node='misago:admin'):
+    def visible_branches(self, request):
         if not self.nodes_dict:
         if not self.nodes_dict:
             self.nodes_dict = self.build_nodes_dict()
             self.nodes_dict = self.build_nodes_dict()
-        return self.nodes_dict[node].children()
 
 
-    def parent(self):
-        raise ValueError("Root node has no parent!")
+        branches = []
+
+        if request.resolver_match.namespace in self.nodes_dict:
+            node = self.nodes_dict[request.resolver_match.namespace]
+            while node:
+                children = node.children_as_dicts()
+                if children:
+                    branches.append(children)
+                node = node.parent
+
+        branches.reverse()
+
+        # Lowest level branch, active link
+        for node in branches[0]:
+            node['is_active'] = node['link'] in request.path
+
+        # Other levels branches
+        for branch in branches[1:]:
+            for node in branch:
+                active = node['namespace'] in request.resolver_match.namespace
+                node['is_active'] = active
+
+        # Hack for index link
+        full_url_name = '%s:%s' % (request.resolver_match.namespace,
+                                   request.resolver_match.url_name)
+        if full_url_name != 'misago:admin:index':
+            branches[0][0]['is_active'] = False
+
+        return branches
 
 
 
 
 site = AdminHierarchyBuilder()
 site = AdminHierarchyBuilder()

+ 21 - 0
misago/admin/urls.py

@@ -7,4 +7,25 @@ urlpatterns = patterns('misago.admin.views',
     # any request with path that falls below this one is assumed to be directed
     # any request with path that falls below this one is assumed to be directed
     # at Misago Admin and will be checked by Misago Admin Middleware
     # at Misago Admin and will be checked by Misago Admin Middleware
     url(r'^$', 'index.admin_index', name='index'),
     url(r'^$', 'index.admin_index', name='index'),
+    url(r'^settings/$', 'index.admin_index', name='settings'),
+)
+
+
+"""
+TEST PATTERNS FOR GOD OF TEST PATTERNS
+"""
+
+userpatterns = patterns('misago.admin.views',
+    # top lel at users fake views
+    url(r'^$', 'index.admin_index', name='list'),
+)
+
+
+newpatterns = patterns('',
+    url(r'^', include(userpatterns, namespace='accounts')),
+)
+
+
+urlpatterns += patterns('',
+    url(r'^users/', include(newpatterns, namespace='users')),
 )
 )

+ 1 - 1
misago/admin/views/__init__.py

@@ -15,7 +15,7 @@ def render(request, template, context=None):
     context = context or {}
     context = context or {}
 
 
     context.update({
     context.update({
-            'admin_sections': site.children('misago:admin'),
+            'navigation': site.visible_branches(request),
         })
         })
 
 
     return dj_render(request, template, context)
     return dj_render(request, template, context)

+ 2 - 1
misago/admin/views/index.py

@@ -2,4 +2,5 @@ from misago.admin.views import render
 
 
 
 
 def admin_index(request):
 def admin_index(request):
-    return render(request, 'misago/admin/index.html')
+    namespace = request.resolver_match.namespace
+    return render(request, 'misago/admin/index.html', {'namespace': namespace})

+ 24 - 0
misago/conf/models.py

@@ -69,6 +69,30 @@ from django.utils.translation import ugettext_lazy as _
 admin_site.add_node(
 admin_site.add_node(
     parent='misago:admin',
     parent='misago:admin',
     link='misago:admin:index',
     link='misago:admin:index',
+    icon='fa fa-home',
+    name=_("Home"),
+    )
+
+admin_site.add_node(
+    parent='misago:admin',
+    link='misago:admin:settings',
     icon='fa fa-gears',
     icon='fa fa-gears',
     name=_("Settings"),
     name=_("Settings"),
     )
     )
+
+admin_site.add_node(
+    parent='misago:admin',
+    namespace='users',
+    after='misago:admin:settings',
+    link='misago:admin:users:accounts:list',
+    icon='fa fa-user',
+    name=_("Users"),
+    )
+
+admin_site.add_node(
+    parent='misago:admin:users',
+    namespace='accounts',
+    link='misago:admin:users:accounts:list',
+    icon='fa fa-user',
+    name=_("Accounts"),
+    )

+ 8 - 4
misago/templates/misago/admin/base.html

@@ -3,17 +3,21 @@
 
 
 
 
 {% block body %}
 {% block body %}
-<h1>Sections:</h1>
+<h1>Nodes:</h1>
+{% for level in navigation %}
+<hr>
+<h2>Level {{ forloop.counter }}</h2>
 <ul>
 <ul>
-  {% for node in admin_sections %}
+  {% for node in level %}
   <li>
   <li>
-    <a href="{% url node.link %}">
+    <a href="{{ node.link }}">
       <span class="{{ node.icon }}"></span>
       <span class="{{ node.icon }}"></span>
-      {{ node.name }}
+      {{ node.name }} {% if node.is_active %}(*){% endif %}
     </a>
     </a>
   </li>
   </li>
   {% endfor %}
   {% endfor %}
 </ul>
 </ul>
+{% endfor %}
 
 
 
 
 {% block content %}{% endblock %}
 {% block content %}{% endblock %}

+ 2 - 1
misago/templates/misago/admin/index.html

@@ -7,6 +7,7 @@
 
 
 {% block content %}
 {% block content %}
 <div class="container">
 <div class="container">
-  <p>Admin index!</p>
+  <h3>Admin Placeholder View</h3>
+  <p class="lead">Requested namespace: <strong>{{ namespace }}</strong></p>
 </div>
 </div>
 {% endblock content %}
 {% endblock content %}