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