Skip to content

Commit

Permalink
Allow MenuItem url to be callable (#112)
Browse files Browse the repository at this point in the history
Fixes #70.
Also closes #71 by incorporating its code.
  • Loading branch information
kytta authored Nov 27, 2022
2 parents 81f751d + 764faa1 commit 72e930f
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 3 deletions.
11 changes: 9 additions & 2 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions simple_menu/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
18 changes: 17 additions & 1 deletion simple_menu/tests/test_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'):
Expand Down Expand Up @@ -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 = {}
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 72e930f

Please sign in to comment.