11import copy
2-
3-
4- from django .core .urlresolvers import reverse
5- from django .core .urlresolvers import NoReverseMatch
62from django .core .exceptions import ImproperlyConfigured
3+ from django .urls import reverse , NoReverseMatch
74
8- from . import utils as util
5+ from .utils import get_callable
96
107
118class MenuBase (object ):
@@ -19,14 +16,15 @@ def __init__(self):
1916 def save_user_state (self , request ):
2017 """
2118 Given a request object, store the current user attributes
19+ :param request: HttpRequest
2220 """
2321 self .request = request
2422 self .path = request .path
2523
26- def is_validated (self , item_dict ):
24+ def _is_validated (self , item_dict ):
2725 """
28- Given a menu item dictionary, it returns true if menu item should be only shown
29- to users if a set validators are true. (e.g. show if user is remember of admin group)
26+ Given a menu item dictionary, it returns true if the user passes all the validator's conditions, it means,
27+ if the user passes all the conditions, the user can see the menu
3028 """
3129 validators = item_dict .get ('validators' )
3230 if not validators :
@@ -35,106 +33,104 @@ def is_validated(self, item_dict):
3533 if not isinstance (validators , (list , tuple )):
3634 raise ImproperlyConfigured ("validators must be a list" )
3735
38- for validate in validators :
39- if isinstance (validate , tuple ):
40- if len (validate ) <= 1 :
41- raise ImproperlyConfigured ("You are passing a tuple validator with no params %s" % str (validate ))
42- func = util . get_callable (validate [0 ])
36+ for validator in validators :
37+ if isinstance (validator , tuple ):
38+ if len (validator ) <= 1 :
39+ raise ImproperlyConfigured ("You are passing a tuple validator without args %s" % str (validator ))
40+ func = get_callable (validator [0 ])
4341 # Using a python slice to get all items after the first to build function args
44- args = validate [1 :]
42+ args = validator [1 :]
43+ # Pass the request as first arg by default
4544 return func (self .request , * args )
4645 else :
47- func = util . get_callable (validate )
46+ func = get_callable (validator )
4847 return func or func (self .request ) # pragma: no cover
4948
50- def has_name (self , item_dict ):
49+ def _has_attr (self , item_dict , attr ):
50+ """
51+ Given a menu item dictionary, it returns true if an attr is set.
52+ """
53+ if item_dict .get (attr , False ):
54+ return True
55+ return False
56+
57+ def _get_icon (self , parent_dict ):
5158 """
52- Given a menu item dictionary, it returns true if attribute `name` is set.
59+ Given a menu item dictionary, this returns an icon class if one exist, or
60+ returns an empty string.
5361 """
54- yep = True
55- if not item_dict .get ('name' , False ):
56- yep = False
57- return yep
62+ return parent_dict .get ('icon_class' , '' )
5863
59- def get_url (self , item_dict ):
64+ def _get_url (self , item_dict ):
6065 """
6166 Given a menu item dictionary, it returns the URL or an empty string.
6267 """
63- final_url = ''
6468 url = item_dict .get ('url' , '' )
6569 try :
6670 final_url = reverse (** url ) if type (url ) is dict else reverse (url )
6771 except NoReverseMatch :
6872 final_url = url
6973 return final_url
7074
71- def has_url (self , item_dict ):
72- """
73- Given a menu item dictionary, it returns true if attribute `url` is set.
74- """
75- if not self .get_url (item_dict ):
76- return False
77- return True
78-
79- def is_selected (self , item_dict ):
75+ def _is_selected (self , item_dict ):
8076 """
8177 Given a menu item dictionary, it returns true if `url` is on path.
8278 """
83- url = self .get_url (item_dict )
84- if len (url ) and url == self .path :
85- return True
86- return False
79+ url = self ._get_url (item_dict )
80+ return url == self .path
8781
88- def process_breadcrums (self , menu_list ):
82+ def _process_breadcrums (self , menu_list ):
8983 """
9084 Given a menu list, it marks the items on the current path as selected, which
9185 can be used as breadcrumbs
9286 """
9387 for item in menu_list :
9488 if item ['submenu' ]:
95- item ['selected' ] = self .process_breadcrums (item ['submenu' ])
89+ item ['selected' ] = self ._process_breadcrums (item ['submenu' ])
9690 if item ['selected' ]:
9791 return True
9892 return False
9993
100- def get_submenu_list (self , parent_dict , depth ):
94+ def _get_submenu_list (self , parent_dict ):
10195 """
10296 Given a menu item dictionary, it returns a submenu if one exist, or
10397 returns None.
10498 """
10599 submenu = parent_dict .get ('submenu' , None )
106- if submenu is not None :
100+ if submenu :
107101 for child_dict in submenu :
108- child_dict ['validators' ] = list (set (list (parent_dict .get ('validators' , [])) +
109- list (child_dict .get ('validators' , []))))
110- submenu = self .generate_menu (submenu , depth )
102+ # This does a join between the menu item validators and submenu item validators and stores it on the
103+ # submenu's validators
104+ child_dict ['validators' ] = list (
105+ set (list (parent_dict .get ('validators' , [])) + list (child_dict .get ('validators' , [])))
106+ )
107+ submenu = self .generate_menu (submenu )
111108 if not submenu :
112109 submenu = None
113110 return submenu
114111
115- def get_menu_list (self , list_dict ):
112+ def _get_menu_list (self , list_dict ):
116113 """
117114 A generator that returns only the visible menu items.
118115 """
119116 for item in list_dict :
120- if self .has_name (item ) and self .has_url (item ):
121- if self .is_validated (item ):
117+ if self ._has_attr (item , 'name' ) and self ._has_attr (item , 'url' ):
118+ if self ._is_validated (item ):
122119 yield copy .copy (item )
123120
124- def generate_menu (self , list_dict , depth = None ):
121+ def generate_menu (self , list_dict ):
125122 """
126123 Given a list of dictionaries, returns a menu list.
127124 """
128125 visible_menu = []
129- current_depth = depth or 0
130- for item in self .get_menu_list (list_dict ):
131- item ['depth' ] = current_depth
132- item ['url' ] = self .get_url (item )
133- item ['selected' ] = self .is_selected (item )
134- item ['submenu' ] = self .get_submenu_list (item , depth = current_depth + 1 )
126+ for item in self ._get_menu_list (list_dict ):
127+ item ['url' ] = self ._get_url (item )
128+ item ['selected' ] = self ._is_selected (item )
129+ item ['submenu' ] = self ._get_submenu_list (item )
130+ item ['icon_class' ] = self ._get_icon (item )
135131 visible_menu .append (item )
136132
137- self .process_breadcrums (visible_menu )
133+ self ._process_breadcrums (visible_menu )
138134
139135 return visible_menu
140136
0 commit comments