28
28
from ivle.webapp.base.views import BaseView
29
29
from ivle.webapp.base.plugins import ViewPlugin, OverlayPlugin
30
30
from ivle.webapp.errors import HTTPError, Unauthorized
31
from ivle.webapp.publisher import NoPath
32
from ivle.webapp.breadcrumbs import Breadcrumber
34
32
class XHTMLView(BaseView):
41
39
template = 'template.html'
42
45
allow_overlays = True
43
breadcrumb_text = None
46
def __init__(self, *args, **kwargs):
47
super(XHTMLView, self).__init__(*args, **kwargs)
49
# We use a single loader for all views, so we can cache the
50
# parsed templates. auto_reload is convenient and has a minimal
51
# performance penalty, so we'll leave it on.
52
if self.__class__._loader is None:
53
self.__class__._loader = genshi.template.TemplateLoader(
54
".", auto_reload=True,
57
self.overlay_blacklist = []
59
self.plugin_scripts = {}
60
self.plugin_styles = {}
61
self.scripts_init = []
63
self.extra_breadcrumbs = []
64
self.overlay_blacklist = []
66
def get_context_ancestry(self, req):
67
return req.publisher.get_ancestors(self.context)
46
overlay_blacklist = []
48
def __init__(self, req, **kwargs):
50
setattr(self, key, kwargs[key])
69
52
def filter(self, stream, ctx):
81
64
app_template = os.path.join(os.path.dirname(
82
65
inspect.getmodule(self).__file__), self.template)
83
tmpl = self._loader.load(app_template)
66
loader = genshi.template.TemplateLoader(".", auto_reload=True)
67
tmpl = loader.load(app_template)
84
68
app = self.filter(tmpl.generate(viewctx), viewctx)
112
96
ctx['scripts_init'] = self.scripts_init + overlay_bits[3]
113
97
ctx['app_template'] = app
114
98
ctx['title_img'] = media_url(req, CorePlugin,
115
"images/chrome/root-breadcrumb.png")
117
ancestry = self.get_context_ancestry(req)
121
crumber = Breadcrumber(req)
123
ctx['breadcrumbs'] = []
124
if not req.publicmode:
125
for ancestor in ancestry:
126
crumb = crumber.crumb(ancestor)
130
if hasattr(crumb, 'extra_breadcrumbs_before'):
131
ctx['breadcrumbs'].extend(crumb.extra_breadcrumbs_before)
132
ctx['breadcrumbs'].append(crumb)
133
if hasattr(crumb, 'extra_breadcrumbs_after'):
134
ctx['breadcrumbs'].extend(crumb.extra_breadcrumbs_after)
136
# If the view has specified text for a breadcrumb, add one.
137
if self.breadcrumb_text:
138
ctx['breadcrumbs'].append(ViewBreadcrumb(req, self))
140
# Allow the view to add its own fake breadcrumbs.
141
ctx['breadcrumbs'].extend(self.extra_breadcrumbs)
99
"images/chrome/title.png")
143
100
self.populate_headings(req, ctx)
144
tmpl = self._loader.load(os.path.join(os.path.dirname(__file__),
101
tmpl = loader.load(os.path.join(os.path.dirname(__file__),
145
102
'ivle-headings.html'))
146
103
req.write(tmpl.generate(ctx).render('xhtml', doctype='xhtml'))
173
130
for tab in plugin.tabs:
174
# tab is a tuple: name, title, desc, icon, path, weight, admin
175
# (Admin is optional, defaults to false)
131
# tab is a tuple: name, title, desc, icon, path
177
133
new_app['this_app'] = hasattr(self, 'tab') \
178
134
and tab[0] == self.tab
186
142
ctx['favicon'] = icon_url
188
144
new_app['has_icon'] = False
189
# The following check is here, so it is AFTER setting the
190
# icon, but BEFORE actually installing the tab in the menu
191
if len(tab) > 6 and tab[6]:
193
if not (req.user and req.user.admin):
195
145
new_app['path'] = req.make_path(tab[4])
196
146
new_app['desc'] = tab[2]
197
147
new_app['name'] = tab[1]
243
193
class XHTMLErrorView(XHTMLView):
244
194
template = 'xhtmlerror.html'
246
def __init__(self, req, context, lastobj):
247
super(XHTMLErrorView, self).__init__(req, context)
248
self.lastobj = lastobj
250
def get_context_ancestry(self, req):
251
return req.publisher.get_ancestors(self.lastobj)
196
def __init__(self, req, exception):
197
self.context = exception
253
199
def populate(self, req, ctx):
255
200
ctx['exception'] = self.context
256
req.headers_out['X-IVLE-Error'] = self.context.message
258
202
class XHTMLUnauthorizedView(XHTMLErrorView):
259
203
template = 'xhtmlunauthorized.html'
261
def __init__(self, req, exception, lastobj):
262
super(XHTMLUnauthorizedView, self).__init__(req, exception, lastobj)
205
def __init__(self, req, exception):
206
super(XHTMLUnauthorizedView, self).__init__(req, exception)
264
if not req.publicmode and req.user is None:
265
209
# Not logged in. Redirect to login page.
266
210
if req.uri == '/':
267
211
query_string = ''
270
214
req.throw_redirect('/+login' + query_string)
274
class ViewBreadcrumb(object):
275
def __init__(self, req, context):
277
self.context = context
281
return self.context.breadcrumb_text