update
[prawokultury.git] / menu / helpers.py
1 from django.utils.translation import get_language
2
3
4 class MenuItem(object):
5     html_id = None
6
7     class InvalidMenuItem(BaseException):
8         pass
9
10     def __init__(self, url, title, html_id=None, more_urls=None, langs=None):
11         self.url = url
12         self.title = title
13         self.html_id = html_id
14         self.more_urls = more_urls or set()
15         self.langs = langs
16
17     def is_valid(self):
18         return not (self.langs and get_language() not in self.langs)
19
20     def is_active(self, request, value):
21         url = request.get_full_path()
22         if url.startswith(str(self.url)):
23             return True
24         for other_url in self.more_urls:
25             if url.startswith(str(other_url)):
26                 return True
27         return False
28
29     def check_active(self, request, value):
30         try:
31             self.active = self.is_active(request, value)
32         except self.InvalidMenuItem, e:
33             pass
34
35     def get_url(self):
36         return self.url
37
38     def get_title(self):
39         return self.title
40
41
42 class ObjectMenuItem(MenuItem):
43     """Menu item corresponding to an object.
44
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}.
47     """
48     def __init__(self,
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)
52         self.obj = obj
53         self.obj_get = obj_get
54         self.rev_lookups = rev_lookups
55
56     def get_object(self):
57         try:
58             return self.obj or self.obj_get()
59         except BaseException, e:
60             raise self.InvalidMenuItem(e)
61
62     def get_title(self):
63         return self.title or unicode(self.get_object())
64
65     def get_url(self):
66         return self.url or self.get_object().get_absolute_url()
67
68     def is_valid(self):
69         if not super(ObjectMenuItem, self).is_valid():
70             return False
71         try:
72             self.get_object()
73         except self.InvalidMenuItem:
74             return False
75         return True
76
77     def is_active(self, request, value):
78         if value == self.get_object():
79             return True
80         if self.rev_lookups:
81             for model, manager in self.rev_lookups.items():
82                 if (isinstance(value, model) and 
83                         self.get_object() in getattr(value, manager).all()):
84                     return True
85         return False
86
87
88 class ModelMenuItem(MenuItem):
89     """Menu item corresponding to a model, optionally filtered by some fields."""
90
91     def __init__(self, model, url, field_lookups=None, title=None, html_id=None):
92         if title is None:
93             title = unicode(model)
94         super(ModelMenuItem, self).__init__(title=title, url=url, html_id=html_id)
95         self.model = model
96         self.field_lookups = field_lookups
97
98     def is_active(self, request, value):
99         if value == self.model and not self.field_lookups:
100             return True
101         if str(self.url) == request.get_full_path():
102             return True
103         if isinstance(value, self.model) and self.field_lookups:
104             lookups_ok = True
105             for field, lookup in self.field_lookups.items():
106                 if getattr(value, field) != lookup:
107                     lookups_ok = False
108             if lookups_ok:
109                 return True
110         return False
111
112     def get_title(self):
113         return self.title or unicode(self.model)