Skip to content
Snippets Groups Projects
Verified Commit fa91ce4a authored by Nik | Klampfradler's avatar Nik | Klampfradler
Browse files

Merge remote-tracking branch 'natureshadow/feature/related_views'

parents 75a0e1f6 84c80f34
No related branches found
No related tags found
No related merge requests found
......@@ -9,3 +9,5 @@ Contributors
============
`Jonathan Weth <https://github.com/hansegucker>`__ - dev@jonathanweth.de
`Dominik George <https://www.openhub.net/accounts/Natureshadow>`__ - nik@naturalnet.de
......@@ -11,6 +11,7 @@ Django Menu Generator uses python dictionaries to represent the menu items, usua
"url": URL spec,
"root": True | False,
"related_urls": [ list of related URLs ],
"related_views": [ list of related views ],
"validators": [ list of validators ],
"submenu": Dictionary like this
}
......@@ -25,6 +26,8 @@ Where each key is as follows:
- ``related_urls``: If one of these URLs is part of the path on the currently opened page, the menu item will be marked as selected (format of URLs like described at :doc:`urls`)
- ``related_views``: If the currently opened page resolves to one of these views, the menu item will be marked as selected.
- ``root``: A flag to indicate this item is the root of a path, with this you can correctly mark nested menus as selected.
- ``validators``: See :doc:`validators`
......
......@@ -5,9 +5,9 @@ from django.core.exceptions import ImproperlyConfigured
from .utils import get_callable, parse_url, path_startswith
if django.VERSION >= (1, 10): # pragma: no cover
from django.urls import reverse, NoReverseMatch
from django.urls import resolve, reverse, NoReverseMatch
else:
from django.core.urlresolvers import reverse, NoReverseMatch
from django.core.urlresolvers import resolve, reverse, NoReverseMatch
class MenuBase(object):
......@@ -83,12 +83,20 @@ class MenuBase(object):
related_urls = item_dict.get('related_urls', [])
return [parse_url(url) for url in related_urls]
def _get_related_views(self, item_dict):
"""
Given a menu item dictionary, it returns the relateds viewss or an empty list.
"""
related_views = item_dict.get('related_views', [])
return related_views
def _is_selected(self, item_dict):
"""
Given a menu item dictionary, it returns true if `url` is on path,
unless the item is marked as a root, in which case returns true if `url` is part of path.
If related URLS are given, it also returns true if one of the related URLS is part of path.
If related views are given, it also returns true if the path maps to one of these views.
"""
url = self._get_url(item_dict)
if self._is_root(item_dict) and path_startswith(self.path, url):
......@@ -100,6 +108,9 @@ class MenuBase(object):
for related_url in self._get_related_urls(item_dict):
if path_startswith(self.path, related_url):
return True
# Resolve URL and check if it relates to a related views
if resolve(self.path).func in self._get_related_views(item_dict):
return True
return False
def _is_root(self, item_dict):
......
......@@ -2,6 +2,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.http import HttpRequest
from django.test import TestCase
from .urls import testview
from .utils import TestUser, is_main_site, is_paid_user
from ..menu import MenuBase
from ..templatetags.menu_generator import get_menu
......@@ -306,3 +307,48 @@ class MenuTestCase(TestCase):
self.assertEqual(nav[0]["selected"], True)
self.assertEqual(nav[0]["submenu"][0]["selected"], True)
self.assertEqual(nav[0]["submenu"][1]["selected"], False)
def test_generate_menu_selected_related_views_simple(self):
self.request.user = TestUser(authenticated=True)
self.request.path = "/known-view/"
self.menu.save_user_state(self.request)
list_dict = [
{
"name": "parent1",
"url": "/user/account/",
"related_views": [testview],
}
]
nav = self.menu.generate_menu(list_dict)
self.assertEqual(len(nav), 1)
self.assertEqual(nav[0]["selected"], True)
def test_generate_menu_selected_related_views_submenu(self):
self.request.user = TestUser(authenticated=True)
self.request.path = "/known-view/"
self.menu.save_user_state(self.request)
list_dict = [
{
"name": "parent1",
"url": "/user/account/",
"submenu": [
{
"name": "child1",
"url": '/user/account/profile/',
"related_views": [testview]
},
{
"name": "child2",
"url": 'named_url',
"related_views": []
},
],
}
]
nav = self.menu.generate_menu(list_dict)
self.assertEqual(len(nav), 1)
self.assertEqual(nav[0]["selected"], True)
self.assertEqual(nav[0]["submenu"][0]["selected"], True)
self.assertEqual(nav[0]["submenu"][1]["selected"], False)
from django.conf.urls import url
def testview(request):
return 'foo'
urlpatterns = [
url('', lambda: 'foo'),
url('named-url', lambda: 'foo', name='named_url'),
url('named-with-params/(?P<pk>\d+)/', lambda: 'foo', name='named_with_params')
url(r'named-url', lambda: 'foo', name='named_url'),
url(r'named-with-params/(?P<pk>\d+)/', lambda: 'foo', name='named_with_params'),
url(r'known-view', testview, name='known_view'),
url(r'', lambda: 'foo'),
]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment