Browse Source

Revamped admin extensions

Rafał Pitoń 11 years ago
parent
commit
c587b8cc1f

+ 16 - 9
docs/developers/admin_actions.rst

@@ -164,18 +164,25 @@ It's required to return dict that will be then used as one of arguments to call
 Registering in Misago Admin
 Registering in Misago Admin
 ===========================
 ===========================
 
 
-Misago Admin Site is just an hierarchy of links defined in apps and registered within ``misago.admin.site`` object.
+Misago Admin Site is just an hierarchy of page, made of two parts: site that contains tree of links relations and ``urlpatterns`` that is included in ``misago:admin`` namespace.
 
 
+When Misago is started, it scans registered apps for ``admin`` module, just like original Django admin does. If module is found, Misago sees if it defines ``MisagoAdminExtension`` class. If such class is found, its instantiated with no arguments, and two of its methods are called:
+
+
+.. function:: register_urlpatterns(self, urlpatterns)
+
+This function allows apps to register new urlpatterns under ``misago:admin`` namespace.
 
 
-Registering urls under ``misago:admin`` namespace
--------------------------------------------------
 
 
-Your admin links will live under ``misago:admin`` namespace, which means they have to be registered in it beforehand. Similiarly to Django, Misago uses small discovery routine which discovers modules that are expected to register their urls in admin.
+.. function:: register_navigation_nodes(self, site)
 
 
-.. warning::
-   Currently only way to register urls in admin site without ingerention into ``misago.admin`` app is to define your patterns in ``models.py`` . Starting with Django 1.7, you will have to make decision where to locate code that will register your links in Misago admin and call it within your app ``apps.py`` initializer.
+This function allows apps to register new links in admin site navigation.
+
+
+Registering urls under ``misago:admin`` namespace
+-------------------------------------------------
 
 
-Admin links are stored within instance of special object :py:class:`misago.admin.urlpatterns.URLPatterns` avaialable under ``misago.admin.urlpatterns``. This object exposes two methods as public api:
+Admin links are stored within instance of special object :py:class:`misago.admin.urlpatterns.URLPatterns` available as ``urlpatterns`` argument passed to ``register_urlpatterns`` method. This object exposes two methods as public api:
 
 
 
 
 .. function:: namespace(path, namespace, parent=None)
 .. function:: namespace(path, namespace, parent=None)
@@ -199,9 +206,9 @@ Registers urlpatterns under defined namespace. Expects first argument to be name
 Registering urls in navigation
 Registering urls in navigation
 ------------------------------
 ------------------------------
 
 
-Your urls have to be discoverable by your users. Easiest way is to do this is to display primary link to your admin in admin site navigation.
+Your urls have to be discoverable by your users. Easiest way is to do this is to display primary link to your admin action in admin site navigation.
 
 
-This navigation is controlled by instance of the :py:class:`misago.admin.hierarchy.AdminHierarchyBuilder` class available under ``misago.admin.site`` path. This class has plenty of functions, but it's public api consists of one method:
+This navigation is controlled by instance of the :py:class:`misago.admin.hierarchy.AdminHierarchyBuilder` class available as ``site`` argument passed to ``register_navigation_nodes`` method of your ``MisagoAdminExtension`` class. It has plenty of functions, but it's public api consists of one method:
 
 
 
 
 .. function:: add_node(parent='misago:admin', after=None, before=None,
 .. function:: add_node(parent='misago:admin', after=None, before=None,

+ 34 - 0
misago/acl/admin.py

@@ -0,0 +1,34 @@
+from django.conf.urls import url
+from django.utils.translation import ugettext_lazy as _
+from misago.acl.views import RolesList, NewRole, EditRole, DeleteRole
+
+
+class MisagoAdminExtension(object):
+    def register_urlpatterns(self, urlpatterns):
+        # Permissions section
+        urlpatterns.namespace(r'^permissions/', 'permissions')
+
+        # Roles
+        urlpatterns.namespace(r'^users/', 'users', 'permissions')
+        urlpatterns.patterns('permissions:users',
+            url(r'^$', RolesList.as_view(), name='index'),
+            url(r'^new/$', NewRole.as_view(), name='new'),
+            url(r'^edit/(?P<role_id>\d+)/$', EditRole.as_view(), name='edit'),
+            url(r'^delete/(?P<role_id>\d+)/$', DeleteRole.as_view(), name='delete'),
+        )
+
+    def register_navigation_nodes(self, site):
+        site.add_node(
+            parent='misago:admin',
+            after='misago:admin:users:accounts:index',
+            namespace='misago:admin:permissions',
+            link='misago:admin:permissions:users:index',
+            name=_("Permissions"),
+            icon='fa fa-adjust')
+
+        site.add_node(
+            parent='misago:admin:permissions',
+            namespace='misago:admin:permissions:users',
+            link='misago:admin:permissions:users:index',
+            name=_("User roles"),
+            icon='fa fa-th-large')

+ 0 - 17
misago/acl/adminurls.py

@@ -1,17 +0,0 @@
-from django.conf.urls import url
-from misago.admin import urlpatterns
-from misago.acl.views import RolesList, NewRole, EditRole, DeleteRole
-
-
-# Users section
-urlpatterns.namespace(r'^permissions/', 'permissions')
-
-
-# Roles
-urlpatterns.namespace(r'^users/', 'users', 'permissions')
-urlpatterns.patterns('permissions:users',
-    url(r'^$', RolesList.as_view(), name='index'),
-    url(r'^new/$', NewRole.as_view(), name='new'),
-    url(r'^edit/(?P<role_id>\d+)/$', EditRole.as_view(), name='edit'),
-    url(r'^delete/(?P<role_id>\d+)/$', DeleteRole.as_view(), name='delete'),
-)

+ 1 - 20
misago/acl/models.py

@@ -1,6 +1,4 @@
 from django.db import models
 from django.db import models
-from django.utils.translation import ugettext_lazy as _
-from misago.admin import site
 from misago.acl import version as acl_version
 from misago.acl import version as acl_version
 import base64
 import base64
 try:
 try:
@@ -18,7 +16,7 @@ class BaseRole(models.Model):
         abstract = True
         abstract = True
 
 
     def __unicode__(self):
     def __unicode__(self):
-        return unicode(_(self.name))
+        return self.name
 
 
     def save(self, *args, **kwargs):
     def save(self, *args, **kwargs):
         if self.pk:
         if self.pk:
@@ -50,20 +48,3 @@ class BaseRole(models.Model):
 
 
 class Role(BaseRole):
 class Role(BaseRole):
     pass
     pass
-
-
-"""register models in misago admin"""
-site.add_node(
-    parent='misago:admin',
-    after='misago:admin:users:accounts:index',
-    namespace='misago:admin:permissions',
-    link='misago:admin:permissions:users:index',
-    name=_("Permissions"),
-    icon='fa fa-adjust')
-
-site.add_node(
-    parent='misago:admin:permissions',
-    namespace='misago:admin:permissions:users',
-    link='misago:admin:permissions:users:index',
-    name=_("User roles"),
-    icon='fa fa-th-large')

+ 1 - 0
misago/admin/__init__.py

@@ -1,5 +1,6 @@
 from misago.admin.hierarchy import site  # noqa
 from misago.admin.hierarchy import site  # noqa
 from misago.admin.urlpatterns import urlpatterns  # noqa
 from misago.admin.urlpatterns import urlpatterns  # noqa
+from misago.admin.discoverer import discover_misago_admin  # noqa
 
 
 
 
 default_app_config = 'misago.admin.apps.MisagoAdminConfig'
 default_app_config = 'misago.admin.apps.MisagoAdminConfig'

+ 15 - 0
misago/admin/admin.py

@@ -0,0 +1,15 @@
+from django.conf.urls import url
+from django.utils.translation import ugettext_lazy as _
+from misago.acl.views import RolesList, NewRole, EditRole, DeleteRole
+
+
+class MisagoAdminExtension(object):
+    def register_urlpatterns(self, urlpatterns):
+        pass
+
+    def register_navigation_nodes(self, site):
+        site.add_node(
+            parent='misago:admin',
+            link='misago:admin:index',
+            name=_("Home"),
+            icon='fa fa-home')

+ 18 - 0
misago/admin/discoverer.py

@@ -0,0 +1,18 @@
+from importlib import import_module
+from django.apps import apps
+from misago.admin.hierarchy import site
+from misago.admin.urlpatterns import urlpatterns
+
+
+__ALL__ = ['discover_misago_admin']
+
+
+def discover_misago_admin():
+    for app in apps.get_app_configs():
+        module = import_module(app.name)
+        if hasattr(module, 'admin'):
+            admin_module = import_module('%s.admin' % app.name)
+            if hasattr(admin_module, 'MisagoAdminExtension'):
+                extension = getattr(admin_module, 'MisagoAdminExtension')()
+                extension.register_navigation_nodes(site)
+                extension.register_urlpatterns(urlpatterns)

+ 2 - 8
misago/admin/urls.py

@@ -1,7 +1,6 @@
 import importlib
 import importlib
 from django.conf import settings
 from django.conf import settings
 from django.conf.urls import patterns, include, url
 from django.conf.urls import patterns, include, url
-from django.core.exceptions import ImproperlyConfigured
 from misago import admin
 from misago import admin
 
 
 
 
@@ -14,11 +13,6 @@ urlpatterns = patterns('misago.admin.views',
 )
 )
 
 
 
 
-# Import admin urls
-import misago.conf.adminurls
-import misago.acl.adminurls
-import misago.forums.urls
-import misago.users.urls.admin
-
-# Register discovered patterns
+# Discover admin and register patterns
+admin.discover_misago_admin()
 urlpatterns += admin.urlpatterns()
 urlpatterns += admin.urlpatterns()

+ 19 - 0
misago/conf/admin.py

@@ -0,0 +1,19 @@
+from django.conf.urls import url
+from django.utils.translation import ugettext_lazy as _
+
+
+class MisagoAdminExtension(object):
+    def register_urlpatterns(self, urlpatterns):
+        urlpatterns.namespace(r'^settings/', 'settings')
+
+        urlpatterns.patterns('settings',
+            url(r'^$', 'misago.conf.views.index', name='index'),
+            url(r'^(?P<group_key>(\w|-)+)/$', 'misago.conf.views.group', name='group'),
+        )
+
+    def register_navigation_nodes(self, site):
+        site.add_node(
+            parent='misago:admin',
+            link='misago:admin:settings:index',
+            name=_("Settings"),
+            icon='fa fa-gears')

+ 0 - 10
misago/conf/adminurls.py

@@ -1,10 +0,0 @@
-from django.conf.urls import url
-from misago.admin import urlpatterns
-
-
-urlpatterns.namespace(r'^settings/', 'settings')
-
-urlpatterns.patterns('settings',
-    url(r'^$', 'misago.conf.views.index', name='index'),
-    url(r'^(?P<group_key>(\w|-)+)/$', 'misago.conf.views.group', name='group'),
-)

+ 0 - 18
misago/conf/models.py

@@ -1,6 +1,5 @@
 import base64
 import base64
 from django.db import models
 from django.db import models
-from misago.admin import site as admin_site
 from misago.conf import hydrators
 from misago.conf import hydrators
 try:
 try:
     import cPickle as pickle
     import cPickle as pickle
@@ -94,20 +93,3 @@ class Setting(models.Model):
         if new_extra:
         if new_extra:
             pickled_extra = pickle.dumps(new_extra, pickle.HIGHEST_PROTOCOL)
             pickled_extra = pickle.dumps(new_extra, pickle.HIGHEST_PROTOCOL)
             self.pickled_field_extra = base64.encodestring(pickled_extra)
             self.pickled_field_extra = base64.encodestring(pickled_extra)
-
-
-from django.utils.translation import ugettext_lazy as _
-
-admin_site.add_node(
-    parent='misago:admin',
-    link='misago:admin:index',
-    icon='fa fa-home',
-    name=_("Home"),
-    )
-
-admin_site.add_node(
-    parent='misago:admin',
-    link='misago:admin:settings:index',
-    icon='fa fa-gears',
-    name=_("Settings"),
-    )

+ 64 - 0
misago/forums/admin.py

@@ -0,0 +1,64 @@
+from django.conf.urls import url
+from django.utils.translation import ugettext_lazy as _
+from misago.forums.views.forumsadmin import (ForumsList, NewForum, EditForum,
+                                             DeleteForum, MoveUpForum,
+                                             MoveDownForum)
+from misago.forums.views.permsadmin import (ForumRolesList, NewForumRole,
+                                            EditForumRole, DeleteForumRole,
+                                            RoleForumsACL)
+
+
+class MisagoAdminExtension(object):
+    def register_urlpatterns(self, urlpatterns):
+        # Forums section
+        urlpatterns.namespace(r'^forums/', 'forums')
+
+        # Nodes
+        urlpatterns.namespace(r'^nodes/', 'nodes', 'forums')
+        urlpatterns.patterns('forums:nodes',
+            url(r'^$', ForumsList.as_view(), name='index'),
+            url(r'^new/$', NewForum.as_view(), name='new'),
+            url(r'^edit/(?P<forum_id>\d+)/$', EditForum.as_view(), name='edit'),
+            url(r'^move/up/(?P<forum_id>\d+)/$', MoveUpForum.as_view(), name='up'),
+            url(r'^move/down/(?P<forum_id>\d+)/$', MoveDownForum.as_view(), name='down'),
+            url(r'^delete/(?P<forum_id>\d+)/$', DeleteForum.as_view(), name='delete'),
+        )
+
+        # Forum Roles
+        urlpatterns.namespace(r'^forums/', 'forums', 'permissions')
+        urlpatterns.patterns('permissions:forums',
+            url(r'^$', ForumRolesList.as_view(), name='index'),
+            url(r'^new/$', NewForumRole.as_view(), name='new'),
+            url(r'^edit/(?P<role_id>\d+)/$', EditForumRole.as_view(), name='edit'),
+            url(r'^delete/(?P<role_id>\d+)/$', DeleteForumRole.as_view(), name='delete'),
+        )
+
+        # Change Role Forum Permissions
+        urlpatterns.patterns('permissions:users',
+            url(r'^forums/(?P<role_id>\d+)/$', RoleForumsACL.as_view(), name='forums'),
+        )
+
+    def register_navigation_nodes(self, site):
+        site.add_node(
+            parent='misago:admin',
+            before='misago:admin:permissions:users:index',
+            namespace='misago:admin:forums',
+            link='misago:admin:forums:nodes:index',
+            name=_("Forums"),
+            icon='fa fa-comments')
+
+        site.add_node(
+            parent='misago:admin:forums',
+            namespace='misago:admin:forums:nodes',
+            link='misago:admin:forums:nodes:index',
+            name=_("Forums Hierarchy"),
+            icon='fa fa-sitemap')
+
+        site.add_node(
+            parent='misago:admin:permissions',
+            namespace='misago:admin:permissions:forums',
+            after='misago:admin:permissions:users:index',
+            link='misago:admin:permissions:forums:index',
+            name=_("Forum roles"),
+            icon='fa fa-comments-o')
+

+ 0 - 26
misago/forums/models.py

@@ -4,7 +4,6 @@ from mptt.managers import TreeManager
 from mptt.models import MPTTModel, TreeForeignKey
 from mptt.models import MPTTModel, TreeForeignKey
 from misago.acl import version as acl_version
 from misago.acl import version as acl_version
 from misago.acl.models import BaseRole
 from misago.acl.models import BaseRole
-from misago.admin import site
 from misago.core.utils import subset_markdown, slugify
 from misago.core.utils import subset_markdown, slugify
 
 
 
 
@@ -89,28 +88,3 @@ class RoleForumACL(models.Model):
     role = models.ForeignKey('misago_acl.Role', related_name='forums_acls')
     role = models.ForeignKey('misago_acl.Role', related_name='forums_acls')
     forum = models.ForeignKey('Forum')
     forum = models.ForeignKey('Forum')
     forum_role = models.ForeignKey(ForumRole)
     forum_role = models.ForeignKey(ForumRole)
-
-
-"""register model in misago admin"""
-site.add_node(
-    parent='misago:admin',
-    before='misago:admin:permissions:users:index',
-    namespace='misago:admin:forums',
-    link='misago:admin:forums:nodes:index',
-    name=_("Forums"),
-    icon='fa fa-comments')
-
-site.add_node(
-    parent='misago:admin:forums',
-    namespace='misago:admin:forums:nodes',
-    link='misago:admin:forums:nodes:index',
-    name=_("Forums Hierarchy"),
-    icon='fa fa-sitemap')
-
-site.add_node(
-    parent='misago:admin:permissions',
-    namespace='misago:admin:permissions:forums',
-    after='misago:admin:permissions:users:index',
-    link='misago:admin:permissions:forums:index',
-    name=_("Forum roles"),
-    icon='fa fa-comments-o')

+ 0 - 39
misago/forums/urls.py

@@ -1,39 +0,0 @@
-from django.conf.urls import url
-from misago.admin import urlpatterns
-from misago.forums.views.forumsadmin import (ForumsList, NewForum, EditForum,
-                                             DeleteForum, MoveUpForum,
-                                             MoveDownForum)
-from misago.forums.views.permsadmin import (ForumRolesList, NewForumRole,
-                                            EditForumRole, DeleteForumRole,
-                                            RoleForumsACL)
-
-
-# Forums section
-urlpatterns.namespace(r'^forums/', 'forums')
-
-
-# Nodes
-urlpatterns.namespace(r'^nodes/', 'nodes', 'forums')
-urlpatterns.patterns('forums:nodes',
-    url(r'^$', ForumsList.as_view(), name='index'),
-    url(r'^new/$', NewForum.as_view(), name='new'),
-    url(r'^edit/(?P<forum_id>\d+)/$', EditForum.as_view(), name='edit'),
-    url(r'^move/up/(?P<forum_id>\d+)/$', MoveUpForum.as_view(), name='up'),
-    url(r'^move/down/(?P<forum_id>\d+)/$', MoveDownForum.as_view(), name='down'),
-    url(r'^delete/(?P<forum_id>\d+)/$', DeleteForum.as_view(), name='delete'),
-)
-
-# Forum Roles
-urlpatterns.namespace(r'^forums/', 'forums', 'permissions')
-urlpatterns.patterns('permissions:forums',
-    url(r'^$', ForumRolesList.as_view(), name='index'),
-    url(r'^new/$', NewForumRole.as_view(), name='new'),
-    url(r'^edit/(?P<role_id>\d+)/$', EditForumRole.as_view(), name='edit'),
-    url(r'^delete/(?P<role_id>\d+)/$', DeleteForumRole.as_view(), name='delete'),
-)
-
-
-# Change Role Forum Permissions
-urlpatterns.patterns('permissions:users',
-    url(r'^forums/(?P<role_id>\d+)/$', RoleForumsACL.as_view(), name='forums'),
-)

+ 57 - 0
misago/users/admin.py

@@ -0,0 +1,57 @@
+from django.conf.urls import url
+from django.utils.translation import ugettext_lazy as _
+from misago.users.views.useradmin import UsersList, NewUser, EditUser
+from misago.users.views.rankadmin import (RanksList, NewRank, EditRank,
+                                          DeleteRank, MoveUpRank, MoveDownRank,
+                                          DefaultRank)
+
+
+class MisagoAdminExtension(object):
+    def register_urlpatterns(self, urlpatterns):
+        # Users section
+        urlpatterns.namespace(r'^users/', 'users')
+
+        # Accounts
+        urlpatterns.namespace(r'^accounts/', 'accounts', 'users')
+        urlpatterns.patterns('users:accounts',
+            url(r'^$', UsersList.as_view(), name='index'),
+            url(r'^(?P<page>\d+)/$', UsersList.as_view(), name='index'),
+            url(r'^new/$', NewUser.as_view(), name='new'),
+            url(r'^edit/(?P<user_id>\d+)/$', EditUser.as_view(), name='edit'),
+        )
+
+        # Ranks
+        urlpatterns.namespace(r'^ranks/', 'ranks', 'users')
+        urlpatterns.patterns('users:ranks',
+            url(r'^$', RanksList.as_view(), name='index'),
+            url(r'^new/$', NewRank.as_view(), name='new'),
+            url(r'^edit/(?P<rank_id>\d+)/$', EditRank.as_view(), name='edit'),
+            url(r'^default/(?P<rank_id>\d+)/$', DefaultRank.as_view(), name='default'),
+            url(r'^move/up/(?P<rank_id>\d+)/$', MoveUpRank.as_view(), name='up'),
+            url(r'^move/down/(?P<rank_id>\d+)/$', MoveDownRank.as_view(), name='down'),
+            url(r'^delete/(?P<rank_id>\d+)/$', DeleteRank.as_view(), name='delete'),
+        )
+
+    def register_navigation_nodes(self, site):
+        site.add_node(
+            parent='misago:admin',
+            after='misago:admin:index',
+            namespace='misago:admin:users',
+            link='misago:admin:users:accounts:index',
+            name=_("Users"),
+            icon='fa fa-users')
+
+        site.add_node(
+            parent='misago:admin:users',
+            namespace='misago:admin:users:accounts',
+            link='misago:admin:users:accounts:index',
+            name=_("User Accounts"),
+            icon='fa fa-users')
+
+        site.add_node(
+            parent='misago:admin:users',
+            namespace='misago:admin:users:ranks',
+            link='misago:admin:users:ranks:index',
+            name=_("Ranks"),
+            after='misago:admin:users:accounts:index',
+            icon='fa fa-graduation-cap')

+ 1 - 13
misago/users/models/rankmodel.py

@@ -1,6 +1,4 @@
 from django.db import models, transaction
 from django.db import models, transaction
-from django.utils.translation import ugettext_lazy as _
-from misago.admin import site
 from misago.acl import version as acl_version
 from misago.acl import version as acl_version
 from misago.core.utils import slugify
 from misago.core.utils import slugify
 
 
@@ -34,7 +32,7 @@ class Rank(models.Model):
         get_latest_by = 'order'
         get_latest_by = 'order'
 
 
     def __unicode__(self):
     def __unicode__(self):
-        return unicode(_(self.name))
+        return self.name
 
 
     def save(self, *args, **kwargs):
     def save(self, *args, **kwargs):
         if not self.pk:
         if not self.pk:
@@ -56,13 +54,3 @@ class Rank(models.Model):
             self.order = Rank.objects.latest('order').order + 1
             self.order = Rank.objects.latest('order').order + 1
         except Rank.DoesNotExist:
         except Rank.DoesNotExist:
             self.order = 0
             self.order = 0
-
-
-"""register model in misago admin"""
-site.add_node(
-    parent='misago:admin:users',
-    namespace='misago:admin:users:ranks',
-    link='misago:admin:users:ranks:index',
-    name=_("Ranks"),
-    after='misago:admin:users:accounts:index',
-    icon='fa fa-graduation-cap')

+ 0 - 18
misago/users/models/usermodel.py

@@ -6,7 +6,6 @@ from django.utils import timezone
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 from misago.acl import get_user_acl
 from misago.acl import get_user_acl
 from misago.acl.models import Role
 from misago.acl.models import Role
-from misago.admin import site
 from misago.core.utils import slugify
 from misago.core.utils import slugify
 from misago.users.models import Rank
 from misago.users.models import Rank
 from misago.users.utils import hash_email
 from misago.users.utils import hash_email
@@ -199,20 +198,3 @@ class AnonymousUser(DjangoAnonymousUser):
 
 
     def update_acl_key(self):
     def update_acl_key(self):
         raise TypeError("Can't update ACL key on anonymous users")
         raise TypeError("Can't update ACL key on anonymous users")
-
-
-"""register model in misago admin"""
-site.add_node(
-    parent='misago:admin',
-    after='misago:admin:index',
-    namespace='misago:admin:users',
-    link='misago:admin:users:accounts:index',
-    name=_("Users"),
-    icon='fa fa-users')
-
-site.add_node(
-    parent='misago:admin:users',
-    namespace='misago:admin:users:accounts',
-    link='misago:admin:users:accounts:index',
-    name=_("User Accounts"),
-    icon='fa fa-users')

+ 0 - 33
misago/users/urls/admin.py

@@ -1,33 +0,0 @@
-from django.conf.urls import url
-from misago.admin import urlpatterns
-from misago.users.views.useradmin import UsersList, NewUser, EditUser
-from misago.users.views.rankadmin import (RanksList, NewRank, EditRank,
-                                          DeleteRank, MoveUpRank, MoveDownRank,
-                                          DefaultRank)
-
-
-# Users section
-urlpatterns.namespace(r'^users/', 'users')
-
-
-# Accounts
-urlpatterns.namespace(r'^accounts/', 'accounts', 'users')
-urlpatterns.patterns('users:accounts',
-    url(r'^$', UsersList.as_view(), name='index'),
-    url(r'^(?P<page>\d+)/$', UsersList.as_view(), name='index'),
-    url(r'^new/$', NewUser.as_view(), name='new'),
-    url(r'^edit/(?P<user_id>\d+)/$', EditUser.as_view(), name='edit'),
-)
-
-
-# Ranks
-urlpatterns.namespace(r'^ranks/', 'ranks', 'users')
-urlpatterns.patterns('users:ranks',
-    url(r'^$', RanksList.as_view(), name='index'),
-    url(r'^new/$', NewRank.as_view(), name='new'),
-    url(r'^edit/(?P<rank_id>\d+)/$', EditRank.as_view(), name='edit'),
-    url(r'^default/(?P<rank_id>\d+)/$', DefaultRank.as_view(), name='default'),
-    url(r'^move/up/(?P<rank_id>\d+)/$', MoveUpRank.as_view(), name='up'),
-    url(r'^move/down/(?P<rank_id>\d+)/$', MoveDownRank.as_view(), name='down'),
-    url(r'^delete/(?P<rank_id>\d+)/$', DeleteRank.as_view(), name='delete'),
-)