diff --git a/docs/usage.rst b/docs/usage.rst index 72566ec..89e1709 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -23,8 +23,15 @@ The ``MenuItem`` class should be instantiated and passed to the ``add_item`` class method with the appropriate parameters. ``MenuItem`` accepts a wide number of options to its constructor method, the majority of which are simply attributes that become available in your templates when you're rendering out -the menus. The required arguments to MenuItem are the first two; the title of -the menu and the URL, and the keywords that affect menu generation are: +the menus. + +``MenuItem`` requires the first two arguments: + + * The ``title`` of the item + * The ``url`` of the item, which can be a string or a callable which accepts the request + object and returns a string. + +The keywords that affect menu generation are: * The ``weight`` keyword argument affects sorting of the menu. * The ``children`` keyword argument is either a list of ``MenuItem`` objects, diff --git a/simple_menu/menu.py b/simple_menu/menu.py index fb1df43..d89edf7 100644 --- a/simple_menu/menu.py +++ b/simple_menu/menu.py @@ -194,6 +194,10 @@ def process(self, request): if not self.visible: return + # evaluate our url + if callable(self.url): + self.url = self.url(request) + # evaluate our title if callable(self.title): self.title = self.title(request) diff --git a/simple_menu/tests/test_menu.py b/simple_menu/tests/test_menu.py index 14aa6f6..3b5d35b 100644 --- a/simple_menu/tests/test_menu.py +++ b/simple_menu/tests/test_menu.py @@ -39,6 +39,13 @@ def kids3_2_title(request): return "-".join([request.path, self.kids3_2_desired_title]) return 'kids3-2' + self.kids3_2_desired_url = None + def kids3_2_url(request): + "Allow the url of kids3-2 to be changed" + if self.kids3_2_desired_url is not None: + return '/'.join([request.path, self.kids3_2_desired_url]) + return '/parent3/kids3-2' + def kids2_2_check(request): "Hide kids2-2 whenever the request path ends with /hidden" if request.path.endswith('/hidden'): @@ -66,7 +73,7 @@ def kids3_1(request): kids3 = ( CustomMenuItem("kids3-1", "/parent3/kids3-1", children=kids3_1, slug="salty"), - CustomMenuItem(kids3_2_title, "/parent3/kids3-2") + CustomMenuItem(kids3_2_title, kids3_2_url) ) Menu.items = {} @@ -161,6 +168,15 @@ def test_callable_title(self): items = Menu.process(request, 'test') self.assertEqual(items[1].children[1].title, "/parent3-fun") + def test_callable_url(self): + """ + Ensure callable urls work + """ + self.kids3_2_desired_url = "custom" + request = self.factory.get('/parent3') + items = Menu.process(request, 'test') + self.assertEqual(items[1].children[1].url, "/parent3/custom") + def test_select_parents(self): """ Ensure the MENU_SELECT_PARENTS setting works