Skip to content

Commit 72e930f

Browse files
authored
Allow MenuItem url to be callable (#112)
Fixes #70. Also closes #71 by incorporating its code.
2 parents 81f751d + 764faa1 commit 72e930f

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

Diff for: docs/usage.rst

+9-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,15 @@ The ``MenuItem`` class should be instantiated and passed to the ``add_item``
2323
class method with the appropriate parameters. ``MenuItem`` accepts a wide
2424
number of options to its constructor method, the majority of which are simply
2525
attributes that become available in your templates when you're rendering out
26-
the menus. The required arguments to MenuItem are the first two; the title of
27-
the menu and the URL, and the keywords that affect menu generation are:
26+
the menus.
27+
28+
``MenuItem`` requires the first two arguments:
29+
30+
* The ``title`` of the item
31+
* The ``url`` of the item, which can be a string or a callable which accepts the request
32+
object and returns a string.
33+
34+
The keywords that affect menu generation are:
2835

2936
* The ``weight`` keyword argument affects sorting of the menu.
3037
* The ``children`` keyword argument is either a list of ``MenuItem`` objects,

Diff for: simple_menu/menu.py

+4
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ def process(self, request):
194194
if not self.visible:
195195
return
196196

197+
# evaluate our url
198+
if callable(self.url):
199+
self.url = self.url(request)
200+
197201
# evaluate our title
198202
if callable(self.title):
199203
self.title = self.title(request)

Diff for: simple_menu/tests/test_menu.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ def kids3_2_title(request):
3939
return "-".join([request.path, self.kids3_2_desired_title])
4040
return 'kids3-2'
4141

42+
self.kids3_2_desired_url = None
43+
def kids3_2_url(request):
44+
"Allow the url of kids3-2 to be changed"
45+
if self.kids3_2_desired_url is not None:
46+
return '/'.join([request.path, self.kids3_2_desired_url])
47+
return '/parent3/kids3-2'
48+
4249
def kids2_2_check(request):
4350
"Hide kids2-2 whenever the request path ends with /hidden"
4451
if request.path.endswith('/hidden'):
@@ -66,7 +73,7 @@ def kids3_1(request):
6673

6774
kids3 = (
6875
CustomMenuItem("kids3-1", "/parent3/kids3-1", children=kids3_1, slug="salty"),
69-
CustomMenuItem(kids3_2_title, "/parent3/kids3-2")
76+
CustomMenuItem(kids3_2_title, kids3_2_url)
7077
)
7178

7279
Menu.items = {}
@@ -161,6 +168,15 @@ def test_callable_title(self):
161168
items = Menu.process(request, 'test')
162169
self.assertEqual(items[1].children[1].title, "/parent3-fun")
163170

171+
def test_callable_url(self):
172+
"""
173+
Ensure callable urls work
174+
"""
175+
self.kids3_2_desired_url = "custom"
176+
request = self.factory.get('/parent3')
177+
items = Menu.process(request, 'test')
178+
self.assertEqual(items[1].children[1].url, "/parent3/custom")
179+
164180
def test_select_parents(self):
165181
"""
166182
Ensure the MENU_SELECT_PARENTS setting works

0 commit comments

Comments
 (0)