1 from django.utils.translation import get_language
4 class MenuItem(object):
7 class InvalidMenuItem(BaseException):
10 def __init__(self, url, title, html_id=None, more_urls=None, langs=None):
13 self.html_id = html_id
14 self.more_urls = more_urls or set()
18 return not (self.langs and get_language() not in self.langs)
20 def is_active(self, request, value):
21 url = request.get_full_path()
22 if url.startswith(str(self.url)):
24 for other_url in self.more_urls:
25 if url.startswith(str(other_url)):
29 def check_active(self, request, value):
31 self.active = self.is_active(request, value)
32 except self.InvalidMenuItem, e:
42 class ObjectMenuItem(MenuItem):
43 """Menu item corresponding to an object.
45 If no url or title is provided, get_absolute_url and __unicode__ are used.
46 You can also provide a reverse lookup dictionary, as in {model: field_name}.
49 obj=None, obj_get=None,
50 url=None, rev_lookups=None, title=None, html_id=None):
51 super(ObjectMenuItem, self).__init__(url=url, title=title, html_id=html_id)
53 self.obj_get = obj_get
54 self.rev_lookups = rev_lookups
58 return self.obj or self.obj_get()
59 except BaseException, e:
60 raise self.InvalidMenuItem(e)
63 return self.title or unicode(self.get_object())
66 return self.url or self.get_object().get_absolute_url()
69 if not super(ObjectMenuItem, self).is_valid():
73 except self.InvalidMenuItem:
77 def is_active(self, request, value):
78 if value == self.get_object():
81 for model, manager in self.rev_lookups.items():
82 if (isinstance(value, model) and
83 self.get_object() in getattr(value, manager).all()):
88 class ModelMenuItem(MenuItem):
89 """Menu item corresponding to a model, optionally filtered by some fields."""
91 def __init__(self, model, url, field_lookups=None, title=None, html_id=None):
93 title = unicode(model)
94 super(ModelMenuItem, self).__init__(title=title, url=url, html_id=html_id)
96 self.field_lookups = field_lookups
98 def is_active(self, request, value):
99 if value == self.model and not self.field_lookups:
101 if str(self.url) == request.get_full_path():
103 if isinstance(value, self.model) and self.field_lookups:
105 for field, lookup in self.field_lookups.items():
106 if getattr(value, field) != lookup:
113 return self.title or unicode(self.model)