1 from django.core.urlresolvers import reverse
2 from django.template.defaultfilters import slugify
3 from django import template
4 from forum.utils import html
5 from ui import Registry
8 class Visibility(object):
9 def __init__(self, level='public'):
10 if level not in ['public', 'authenticated', 'staff', 'superuser', 'owner']:
13 self.by_reputation = True
15 raise "Invalid visibility level for ui object: %s" % level
17 self.by_reputation = False
22 def show_to(self, user):
23 if self.by_reputation:
24 res = user.is_authenticated() and (user.reputation >= int(self.level) or user.is_staff or user.is_superuser)
26 res = self.level == 'public' or (user.is_authenticated() and (
27 self.level == 'authenticated' or (
28 self.level == 'superuser' and user.is_superuser) or (
29 self.level == 'staff' and (user.is_staff or user.is_superuser)) or (
30 self.level == 'owner' and user.is_siteowner)))
39 inverted.negated = True
42 Visibility.PUBLIC = Visibility('public')
43 Visibility.AUTHENTICATED = Visibility('authenticated')
44 Visibility.STAFF = Visibility('staff')
45 Visibility.SUPERUSER = Visibility('superuser')
46 Visibility.OWNER = Visibility('owner')
47 Visibility.REPUTED = lambda r: Visibility(r)
51 def __init__(self, url_pattern):
52 self.url_pattern = url_pattern
54 def __call__(self, u, c):
55 return reverse(self.url_pattern)
58 class ObjectBase(object):
59 class Argument(object):
60 def __init__(self, argument):
61 self.argument = argument
63 def __call__(self, context):
64 if callable(self.argument):
65 user = context.get('request', None) and context['request'].user or None
66 return self.argument(user, context)
70 def __init__(self, visibility=None, weight=500):
71 self.visibility = visibility
74 def _visible_to(self, user):
75 return (not self.visibility) or (self.visibility and self.visibility.show_to(user))
77 def can_render(self, context):
79 return self._visible_to(context['request'].user)
82 return self._visible_to(context['viewer'])
89 def render(self, context):
92 class LoopBase(ObjectBase):
93 def update_context(self, context):
98 class Link(ObjectBase):
99 def __init__(self, text, url, attrs=None, pre_code='', post_code='', visibility=None, weight=500):
100 super(Link, self).__init__(visibility, weight)
101 self.text = self.Argument(text)
102 self.url = self.Argument(url)
103 self.attrs = self.Argument(attrs or {})
104 self.pre_code = self.Argument(pre_code)
105 self.post_code = self.Argument(post_code)
107 def render(self, context):
108 return "%s %s %s" % (self.pre_code(context),
109 html.hyperlink(self.url(context), self.text(context), **self.attrs(context)),
110 self.post_code(context))
112 class Include(ObjectBase):
113 def __init__(self, tpl, visibility=None, weight=500):
114 super(Include, self).__init__(visibility, weight)
115 self.template = template.loader.get_template(tpl)
117 def render(self, context):
118 if not isinstance(context, template.Context):
119 context = template.Context(context)
120 return self.template.render(context)
123 class LoopContext(LoopBase):
124 def __init__(self, loop_context, visibility=None, weight=500):
125 super(LoopContext, self).__init__(visibility, weight)
126 self.loop_context = self.Argument(loop_context)
128 def update_context(self, context):
129 context.update(self.loop_context(context))
132 class PageTab(LoopBase):
133 def __init__(self, tab_name, tab_title, url_getter, weight):
134 super(PageTab, self).__init__(weight=weight)
135 self.tab_name = tab_name
136 self.tab_title = tab_title
137 self.url_getter = url_getter
139 def update_context(self, context):
141 tab_name=self.tab_name,
142 tab_title=self.tab_title,
143 tab_url=self.url_getter()
147 class ProfileTab(LoopBase):
148 def __init__(self, name, title, description, url_getter, private=False, render_to=None, weight=500):
149 super(ProfileTab, self).__init__(weight=weight)
152 self.description = description
153 self.url_getter = url_getter
154 self.private = private
155 self.render_to = render_to
157 def can_render(self, context):
158 return (not self.render_to or (self.render_to(context['view_user']))) and (
159 not self.private or (
160 context['view_user'] == context['request'].user or context['request'].user.is_superuser))
162 def update_context(self, context):
165 tab_title=self.title,
166 tab_description = self.description,
167 tab_url=self.url_getter(context['view_user'])
171 class AjaxMenuItem(ObjectBase):
172 def __init__(self, label, url, a_attrs=None, span_label='', span_attrs=None, visibility=None, weight=500):
173 super(AjaxMenuItem, self).__init__(visibility, weight)
174 self.label = self.Argument(label)
175 self.url = self.Argument(url)
176 self.a_attrs = self.Argument(a_attrs or {})
177 self.span_label = self.Argument(span_label)
178 self.span_attrs = self.Argument(span_attrs or {})
180 def render(self, context):
181 return html.buildtag('li',
182 html.buildtag('span', self.span_label(context), **self.span_attrs(context)) + \
183 html.hyperlink(self.url(context), self.label(context), **self.a_attrs(context)),
186 class AjaxMenuGroup(ObjectBase, Registry):
187 def __init__(self, label, items, visibility=None, weight=500):
188 super(AjaxMenuGroup, self).__init__(visibility, weight)
194 def can_render(self, context):
195 if super(AjaxMenuGroup, self).can_render(context):
197 if item.can_render(context): return True
201 def render(self, context):
202 return html.buildtag('li', self.label, **{'class': 'separator'}) + "".join([
203 item.render(context) for item in self if item.can_render(context)
206 class UserMenuItem(AjaxMenuItem):
207 def __init__(self, render_to=None, *args, **kwargs):
208 super(UserMenuItem, self).__init__(*args, **kwargs)
209 self.render_to = render_to
211 def can_render(self, context):
212 return (not self.render_to or (self.render_to(context['user']))) and super(UserMenuItem, self)._visible_to(context['viewer'])