23
24
import genshi.template
25
26
from ivle.webapp.media import media_url
27
from ivle.webapp.core import Plugin as CorePlugin
26
28
from ivle.webapp.base.views import BaseView
27
from ivle.webapp.base.plugins import OverlayPlugin
29
from ivle.webapp.base.plugins import ViewPlugin, OverlayPlugin
28
30
from ivle.webapp.errors import HTTPError, Unauthorized
32
32
class XHTMLView(BaseView):
39
39
template = 'template.html'
40
40
plugin_scripts = {}
42
43
overlay_blacklist = []
44
45
def __init__(self, req, **kwargs):
46
47
setattr(self, key, kwargs[key])
49
def filter(self, stream, ctx):
48
52
def render(self, req):
49
53
req.content_type = 'text/html' # TODO: Detect application/xhtml+xml
57
61
app_template = os.path.join(os.path.dirname(
58
62
inspect.getmodule(self).__file__), self.template)
59
req.write_html_head_foot = False
60
63
loader = genshi.template.TemplateLoader(".", auto_reload=True)
61
64
tmpl = loader.load(app_template)
62
app = tmpl.generate(viewctx)
65
app = self.filter(tmpl.generate(viewctx), viewctx)
64
67
for plugin in self.plugin_scripts:
65
68
for path in self.plugin_scripts[plugin]:
73
76
ctx = genshi.template.Context()
74
77
# XXX: Leave this here!! (Before req.styles is read)
75
ctx['overlays'] = self.render_overlays(req)
76
ctx['app_styles'] = req.styles
77
ctx['scripts'] = req.scripts
78
ctx['overlays'] = self.render_overlays(req) if req.user else []
80
ctx['styles'] = [media_url(req, CorePlugin, 'ivle.css')]
81
ctx['styles'] += req.styles
83
ctx['scripts'] = [media_url(req, CorePlugin, path) for path in
84
('util.js', 'json2.js', 'md5.js')]
85
ctx['scripts'].append(media_url(req, '+external/jquery', 'jquery.js'))
86
ctx['scripts'] += req.scripts
78
88
ctx['scripts_init'] = req.scripts_init
79
89
ctx['app_template'] = app
90
ctx['title_img'] = media_url(req, CorePlugin,
91
"images/chrome/title.png")
80
92
self.populate_headings(req, ctx)
81
93
tmpl = loader.load(os.path.join(os.path.dirname(__file__),
82
94
'ivle-headings.html'))
88
100
def populate_headings(self, req, ctx):
89
101
ctx['favicon'] = None
90
ctx['root_dir'] = ivle.conf.root_dir
91
ctx['public_host'] = ivle.conf.public_host
102
ctx['root_dir'] = req.config['urls']['root']
103
ctx['public_host'] = req.config['urls']['public_host']
104
ctx['svn_base'] = req.config['urls']['svn_addr']
92
105
ctx['write_javascript_settings'] = req.write_javascript_settings
94
107
ctx['login'] = req.user.login
98
111
ctx['login'] = None
99
112
ctx['logged_in'] = False
100
113
ctx['publicmode'] = req.publicmode
114
if hasattr(self, 'help'):
115
ctx['help_path'] = self.help
101
117
ctx['apps_in_tabs'] = []
102
for urlname in ivle.conf.apps.apps_in_tabs:
104
app = ivle.conf.apps.app_url[urlname]
105
new_app['this_app'] = hasattr(self, 'appname') \
106
and urlname == self.appname
108
new_app['has_icon'] = True
109
icon_dir = ivle.conf.apps.app_icon_dir
110
icon_url = ivle.util.make_path(os.path.join(icon_dir, app.icon))
111
new_app['icon_url'] = icon_url
112
if new_app['this_app']:
113
ctx['favicon'] = icon_url
115
new_app['has_icon'] = False
116
new_app['path'] = ivle.util.make_path(urlname)
117
new_app['desc'] = app.desc
118
new_app['name'] = app.name
119
ctx['apps_in_tabs'].append(new_app)
118
for plugin in req.config.plugin_index[ViewPlugin]:
119
if not hasattr(plugin, 'tabs'):
122
for tab in plugin.tabs:
123
# tab is a tuple: name, title, desc, icon, path
125
new_app['this_app'] = hasattr(self, 'tab') \
126
and tab[0] == self.tab
129
if tab[3] is not None:
130
new_app['has_icon'] = True
131
icon_url = media_url(req, plugin, tab[3])
132
new_app['icon_url'] = icon_url
133
if new_app['this_app']:
134
ctx['favicon'] = icon_url
136
new_app['has_icon'] = False
137
new_app['path'] = req.make_path(tab[4])
138
new_app['desc'] = tab[2]
139
new_app['name'] = tab[1]
140
new_app['weight'] = tab[5]
141
ctx['apps_in_tabs'].append(new_app)
143
ctx['apps_in_tabs'].sort(key=lambda tab: tab['weight'])
121
145
def render_overlays(self, req):
122
146
"""Generate XML streams for the overlays.
128
for plugin in req.plugin_index[OverlayPlugin]:
152
if not self.allow_overlays:
155
for plugin in req.config.plugin_index[OverlayPlugin]:
129
156
for overclass in plugin.overlays:
130
157
if overclass in self.overlay_blacklist:
167
194
def __init__(self, req, exception):
168
195
super(XHTMLUnauthorizedView, self).__init__(req, exception)
169
197
if req.user is None:
170
198
# Not logged in. Redirect to login page.
171
req.throw_redirect('/') # XXX: Need proper URL.
202
query_string = '?url=' + urllib.quote(req.uri, safe="/~")
203
req.throw_redirect('/+login' + query_string)