Skip to content

Commit 62a5bd8

Browse files
author
Evan Borgstrom
committed
Now that we copy the MenuItems we can cleanup some of the code
Add support for Django 1.9 in our tests. Mark that we only support 1.6 up in the README, since that's what we have tests for.
1 parent 3cd2478 commit 62a5bd8

File tree

4 files changed

+59
-66
lines changed

4 files changed

+59
-66
lines changed

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ env:
1313
- DJANGO=Django==1.6
1414
- DJANGO=Django==1.7
1515
- DJANGO=Django==1.8
16+
- DJANGO=Django==1.9
1617

1718
matrix:
1819
exclude:
@@ -22,6 +23,12 @@ matrix:
2223
- python: 2.6
2324
env: DJANGO=Django==1.8
2425

26+
- python: 2.6
27+
env: DJANGO=Django==1.9
28+
29+
- python: 3.3
30+
env: DJANGO=Django==1.9
31+
2532
- python: 3.5
2633
env: DJANGO=Django==1.6
2734

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,4 @@ https://django-simple-menu.readthedocs.org
5555
Requirements
5656
------------
5757

58-
Django 1.3+
58+
Django 1.6+

menu/menu.py

Lines changed: 41 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import copy
22
import re
3+
import sys
34

45
from django.conf import settings
6+
from django.utils.text import slugify
57

68
try:
79
from django.apps import apps
@@ -119,19 +121,12 @@ def process(c, request, name=None):
119121
if curitem is not None:
120122
curitem.selected = True
121123

122-
def filter_visible(items):
123-
return [
124-
filter_visible_children(item)
125-
for item in items
126-
if item.visible
127-
]
128-
129-
def filter_visible_children(item):
130-
item.children = filter_visible(item.children)
131-
return item
132-
133124
# return only visible items
134-
visible = filter_visible(items)
125+
visible = [
126+
item
127+
for item in items
128+
if item.visible
129+
]
135130

136131
# determine if we should apply 'selected' to parents when one of their
137132
# children is the 'selected' menu
@@ -178,10 +173,8 @@ def __init__(self, title, url, children=[], weight=1, check=None,
178173

179174
self.url = url
180175
self.title = title
181-
self._title = None
182176
self.visible = visible
183177
self.children = children
184-
self._children = None
185178
self.weight = weight
186179
self.check = check
187180
self.slug = slug
@@ -193,39 +186,57 @@ def __init__(self, title, url, children=[], weight=1, check=None,
193186
for k in kwargs:
194187
setattr(self, k, kwargs[k])
195188

196-
# if title is a callable store a reference to it for later
197-
# then we'll process it at runtime
198-
if callable(title):
199-
self.title = ""
200-
self._title = title
201-
202189
def process(self, request):
203190
"""
204191
process determines if this item should visible, if its selected, etc...
205192
"""
206-
self.check_check(request)
193+
# evaluate our check
194+
if callable(self.check):
195+
self.visible = self.check(request)
196+
197+
# if we're not visible we return since we don't need to do anymore processing
207198
if not self.visible:
208199
return
209200

210-
# evaluate title
211-
self.check_title(request)
201+
# evaluate our title
202+
if callable(self.title):
203+
self.title = self.title(request)
204+
205+
# if no title is set turn it into a slug
206+
if self.slug is None:
207+
# in python3 we don't need to convert to unicode, in python2 slugify
208+
# requires a unicode string
209+
if sys.version_info > (3, 0):
210+
self.slug = slugify(self.title)
211+
else:
212+
self.slug = slugify(unicode(self.title))
212213

213214
# evaluate children
214-
visible_children = []
215-
self.check_children(request)
215+
if callable(self.children):
216+
children = list(self.children(request))
217+
else:
218+
children = list(self.children)
216219

217-
for child in self.children:
220+
for child in children:
221+
child.parent = self
218222
child.process(request)
219-
if child.visible:
220-
visible_children.append(child)
221223

224+
self.children = [
225+
child
226+
for child in children
227+
if child.visible
228+
]
229+
self.children.sort(key=lambda child: child.weight)
230+
231+
# if we have no children and MENU_HIDE_EMPTY then we are not visible and should return
222232
hide_empty = getattr(settings, 'MENU_HIDE_EMPTY', False)
223-
if hide_empty and not self.check and not len(visible_children):
233+
if hide_empty and len(self.children) == 0:
224234
self.visible = False
225235
return
226236

237+
# find out if one of our children is selected, and mark it as such
227238
curitem = None
228-
for item in visible_children:
239+
for item in self.children:
229240
item.selected = False
230241

231242
if item.match_url(request):
@@ -246,36 +257,3 @@ def match_url(self, request):
246257
elif re.match("%s" % self.url, request.path):
247258
matched = True
248259
return matched
249-
250-
def check_children(self, request):
251-
"""
252-
Check children against the given request
253-
"""
254-
if callable(self._children):
255-
children = self._children(request)
256-
elif callable(self.children):
257-
children = self.children(request)
258-
self._children = self.children
259-
else:
260-
children = self.children
261-
262-
children = [child for child in children]
263-
children.sort(key=lambda child: child.weight)
264-
for child in children:
265-
child.parent = self
266-
267-
self.children = children
268-
269-
def check_check(self, request):
270-
"""
271-
Set our visibility based on our check against the given request
272-
"""
273-
if callable(self.check):
274-
self.visible = self.check(request)
275-
276-
def check_title(self, request):
277-
if callable(self._title):
278-
self.title = self._title(request)
279-
if self.slug is None:
280-
self.slug = re.sub(r'[^a-zA-Z0-9\-]+', '_',
281-
self.title.lower()).strip('_')

menu/tests/test_menu.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from menu import Menu, MenuItem
99

1010
# XXX TODO: test MENU_HIDE_EMPTY
11-
# XXX TODO: test check_children
1211

1312
class MenuTests(TestCase):
1413
"""
@@ -52,7 +51,7 @@ def kids3_1(request):
5251
]
5352

5453
kids3 = (
55-
MenuItem("kids3-1", "/parent3/kids3-1", children=kids3_1),
54+
MenuItem("kids3-1", "/parent3/kids3-1", children=kids3_1, slug="salty"),
5655
MenuItem(kids3_2_title, "/parent3/kids3-2")
5756
)
5857

@@ -68,6 +67,15 @@ def kids3_1(request):
6867

6968
self.factory = RequestFactory()
7069

70+
def test_slug(self):
71+
"""
72+
Ensure our slugification works as expected
73+
"""
74+
request = self.factory.get('/parent3/kids3-1')
75+
items = Menu.process(request, 'test')
76+
self.assertEqual(items[1].slug, "parent-3")
77+
self.assertEqual(items[1].children[0].slug, "salty")
78+
7179
def test_exact_url(self):
7280
"""
7381
Ensure that the exact_url setting works

0 commit comments

Comments
 (0)