~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/webapp/base/xhtml.py

  • Committer: William Grant
  • Date: 2010-02-23 08:55:42 UTC
  • mto: This revision was merged to the branch mainline in revision 1674.
  • Revision ID: grantw@unimelb.edu.au-20100223085542-r8xw14bxxoraza51
Permit underscores in all names.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
import ivle.conf
32
 
import ivle.util
 
31
from ivle.webapp.publisher import NoPath
 
32
from ivle.webapp.breadcrumbs import Breadcrumber
33
33
 
34
34
class XHTMLView(BaseView):
35
35
    """
39
39
    """
40
40
 
41
41
    template = 'template.html'
42
 
    plugin_scripts = {}
43
 
    plugin_styles = {}
44
42
    allow_overlays = True
45
 
    overlay_blacklist = []
46
 
 
47
 
    def __init__(self, req, **kwargs):
48
 
        for key in kwargs:
49
 
            setattr(self, key, kwargs[key])
 
43
    breadcrumb_text = None
 
44
 
 
45
    def __init__(self, *args, **kwargs):
 
46
        super(XHTMLView, self).__init__(*args, **kwargs)
 
47
 
 
48
        self.overlay_blacklist = []
 
49
 
 
50
        self.plugin_scripts = {}
 
51
        self.plugin_styles = {}
 
52
        self.scripts_init = []
 
53
 
 
54
        self.extra_breadcrumbs = []
 
55
        self.overlay_blacklist = []
 
56
 
 
57
    def get_context_ancestry(self, req):
 
58
        return req.publisher.get_ancestors(self.context)
 
59
 
 
60
    def filter(self, stream, ctx):
 
61
        return stream
50
62
 
51
63
    def render(self, req):
52
64
        req.content_type = 'text/html' # TODO: Detect application/xhtml+xml
61
73
                        inspect.getmodule(self).__file__), self.template) 
62
74
        loader = genshi.template.TemplateLoader(".", auto_reload=True)
63
75
        tmpl = loader.load(app_template)
64
 
        app = tmpl.generate(viewctx)
 
76
        app = self.filter(tmpl.generate(viewctx), viewctx)
65
77
 
 
78
        view_scripts = []
66
79
        for plugin in self.plugin_scripts:
67
80
            for path in self.plugin_scripts[plugin]:
68
 
                req.scripts.append(media_url(req, plugin, path))
 
81
                view_scripts.append(media_url(req, plugin, path))
69
82
 
 
83
        view_styles = []
70
84
        for plugin in self.plugin_styles:
71
85
            for path in self.plugin_styles[plugin]:
72
 
                req.styles.append(media_url(req, plugin, path))
 
86
                view_styles.append(media_url(req, plugin, path))
73
87
 
74
88
        # Global template
75
89
        ctx = genshi.template.Context()
76
 
        # XXX: Leave this here!! (Before req.styles is read)
77
 
        ctx['overlays'] = self.render_overlays(req) if req.user else []
 
90
 
 
91
        overlay_bits = self.render_overlays(req) if req.user else [[]]*4
 
92
        ctx['overlays'] = overlay_bits[0]
78
93
 
79
94
        ctx['styles'] = [media_url(req, CorePlugin, 'ivle.css')]
80
 
        ctx['styles'] += req.styles
 
95
        ctx['styles'] += view_styles
 
96
        ctx['styles'] += overlay_bits[1]
81
97
 
82
98
        ctx['scripts'] = [media_url(req, CorePlugin, path) for path in
83
99
                           ('util.js', 'json2.js', 'md5.js')]
84
 
        ctx['scripts'] += req.scripts
 
100
        ctx['scripts'].append(media_url(req, '+external/jquery', 'jquery.js'))
 
101
        ctx['scripts'] += view_scripts
 
102
        ctx['scripts'] += overlay_bits[2]
85
103
 
86
 
        ctx['scripts_init'] = req.scripts_init
 
104
        ctx['scripts_init'] = self.scripts_init + overlay_bits[3]
87
105
        ctx['app_template'] = app
88
106
        ctx['title_img'] = media_url(req, CorePlugin,
89
 
                                     "images/chrome/title.png")
 
107
                                     "images/chrome/root-breadcrumb.png")
 
108
        try:
 
109
            ancestry = self.get_context_ancestry(req)
 
110
        except NoPath:
 
111
            ancestry = []
 
112
 
 
113
        crumber = Breadcrumber(req)
 
114
 
 
115
        ctx['breadcrumbs'] = []
 
116
        if not req.publicmode:
 
117
            for ancestor in ancestry:
 
118
                crumb = crumber.crumb(ancestor)
 
119
                if crumb is None:
 
120
                    continue
 
121
 
 
122
                if hasattr(crumb, 'extra_breadcrumbs_before'):
 
123
                    ctx['breadcrumbs'].extend(crumb.extra_breadcrumbs_before)
 
124
                ctx['breadcrumbs'].append(crumb)
 
125
                if hasattr(crumb, 'extra_breadcrumbs_after'):
 
126
                    ctx['breadcrumbs'].extend(crumb.extra_breadcrumbs_after)
 
127
 
 
128
            # If the view has specified text for a breadcrumb, add one.
 
129
            if self.breadcrumb_text:
 
130
                ctx['breadcrumbs'].append(ViewBreadcrumb(req, self))
 
131
 
 
132
            # Allow the view to add its own fake breadcrumbs.
 
133
            ctx['breadcrumbs'].extend(self.extra_breadcrumbs)
 
134
 
90
135
        self.populate_headings(req, ctx)
91
136
        tmpl = loader.load(os.path.join(os.path.dirname(__file__), 
92
137
                                                        'ivle-headings.html'))
97
142
 
98
143
    def populate_headings(self, req, ctx):
99
144
        ctx['favicon'] = None
100
 
        ctx['root_dir'] = ivle.conf.root_dir
101
 
        ctx['public_host'] = ivle.conf.public_host
 
145
        ctx['root_dir'] = req.config['urls']['root']
 
146
        ctx['public_host'] = req.config['urls']['public_host']
 
147
        ctx['svn_base'] = req.config['urls']['svn_addr']
102
148
        ctx['write_javascript_settings'] = req.write_javascript_settings
103
149
        if req.user:
104
150
            ctx['login'] = req.user.login
117
163
                continue
118
164
 
119
165
            for tab in plugin.tabs:
120
 
                # tab is a tuple: name, title, desc, icon, path
 
166
                # tab is a tuple: name, title, desc, icon, path, weight, admin
 
167
                # (Admin is optional, defaults to false)
121
168
                new_app = {}
122
169
                new_app['this_app'] = hasattr(self, 'tab') \
123
170
                                      and tab[0] == self.tab
131
178
                        ctx['favicon'] = icon_url
132
179
                else:
133
180
                    new_app['has_icon'] = False
134
 
                new_app['path'] = ivle.util.make_path(tab[4])
 
181
                # The following check is here, so it is AFTER setting the
 
182
                # icon, but BEFORE actually installing the tab in the menu
 
183
                if len(tab) > 6 and tab[6]:
 
184
                    # Admin-only tab
 
185
                    if not (req.user and req.user.admin):
 
186
                        break
 
187
                new_app['path'] = req.make_path(tab[4])
135
188
                new_app['desc'] = tab[2]
136
189
                new_app['name'] = tab[1]
137
190
                new_app['weight'] = tab[5]
146
199
        scripts_init.
147
200
        """
148
201
        overlays = []
 
202
        styles = []
 
203
        scripts = []
 
204
        scripts_init = []
149
205
        if not self.allow_overlays:
150
 
            return overlays
 
206
            return (overlays, styles, scripts, scripts_init)
151
207
 
152
208
        for plugin in req.config.plugin_index[OverlayPlugin]:
153
209
            for overclass in plugin.overlays:
157
213
                #TODO: Re-factor this to look nicer
158
214
                for mplugin in overlay.plugin_scripts:
159
215
                    for path in overlay.plugin_scripts[mplugin]:
160
 
                        req.scripts.append(media_url(req, mplugin, path))
 
216
                        scripts.append(media_url(req, mplugin, path))
161
217
 
162
218
                for mplugin in overlay.plugin_styles:
163
219
                    for path in overlay.plugin_styles[mplugin]:
164
 
                        req.styles.append(media_url(req, mplugin, path))
 
220
                        styles.append(media_url(req, mplugin, path))
165
221
 
166
 
                req.scripts_init += overlay.plugin_scripts_init
 
222
                scripts_init += overlay.plugin_scripts_init
167
223
 
168
224
                overlays.append(overlay.render(req))
169
 
        return overlays
 
225
        return (overlays, styles, scripts, scripts_init)
170
226
 
171
227
    @classmethod
172
228
    def get_error_view(cls, e):
179
235
class XHTMLErrorView(XHTMLView):
180
236
    template = 'xhtmlerror.html'
181
237
 
182
 
    def __init__(self, req, exception):
183
 
        self.context = exception
 
238
    def __init__(self, req, context, lastobj):
 
239
        super(XHTMLErrorView, self).__init__(req, context)
 
240
        self.lastobj = lastobj
 
241
 
 
242
    def get_context_ancestry(self, req):
 
243
        return req.publisher.get_ancestors(self.lastobj)
184
244
 
185
245
    def populate(self, req, ctx):
 
246
        ctx['req'] = req
186
247
        ctx['exception'] = self.context
 
248
        req.headers_out['X-IVLE-Error'] = self.context.message
187
249
 
188
250
class XHTMLUnauthorizedView(XHTMLErrorView):
189
251
    template = 'xhtmlunauthorized.html'
190
252
 
191
 
    def __init__(self, req, exception):
192
 
        super(XHTMLUnauthorizedView, self).__init__(req, exception)
 
253
    def __init__(self, req, exception, lastobj):
 
254
        super(XHTMLUnauthorizedView, self).__init__(req, exception, lastobj)
193
255
 
194
 
        if req.user is None:
 
256
        if not req.publicmode and req.user is None:
195
257
            # Not logged in. Redirect to login page.
196
258
            if req.uri == '/':
197
259
                query_string = ''
200
262
            req.throw_redirect('/+login' + query_string)
201
263
 
202
264
        req.status = 403
 
265
 
 
266
class ViewBreadcrumb(object):
 
267
    def __init__(self, req, context):
 
268
        self.req = req
 
269
        self.context = context
 
270
 
 
271
    @property
 
272
    def text(self):
 
273
        return self.context.breadcrumb_text