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

« back to all changes in this revision

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

  • Committer: Matt Giuca
  • Date: 2009-02-25 09:40:36 UTC
  • mto: This revision was merged to the branch mainline in revision 1119.
  • Revision ID: matt.giuca@gmail.com-20090225094036-xtchh8klrajzenrb
ivle.css: Fixed display of tabs.
    (We broke them but Firefox lied to us and showed us precisely what we
    wanted to see -- sneaky bugger!)

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
import inspect
21
21
import os.path
 
22
import urllib
22
23
 
23
24
import genshi.template
24
25
 
 
26
from ivle.webapp.media import media_url
 
27
from ivle.webapp.core import Plugin as CorePlugin
25
28
from ivle.webapp.base.views import BaseView
 
29
from ivle.webapp.base.plugins import ViewPlugin, OverlayPlugin
 
30
from ivle.webapp.errors import HTTPError, Unauthorized
26
31
import ivle.conf
27
32
import ivle.util
28
33
 
32
37
    It is expected that apps which use this view will be written using Genshi
33
38
    templates.
34
39
    """
 
40
 
 
41
    template = 'template.html'
 
42
    plugin_scripts = {}
 
43
    plugin_styles = {}
 
44
    allow_overlays = True
 
45
    overlay_blacklist = []
 
46
 
35
47
    def __init__(self, req, **kwargs):
36
48
        for key in kwargs:
37
 
          setattr(self, key, kwargs[key])
 
49
            setattr(self, key, kwargs[key])
38
50
 
39
51
    def render(self, req):
40
52
        req.content_type = 'text/html' # TODO: Detect application/xhtml+xml
47
59
        # view.
48
60
        app_template = os.path.join(os.path.dirname(
49
61
                        inspect.getmodule(self).__file__), self.template) 
50
 
        req.write_html_head_foot = False
51
62
        loader = genshi.template.TemplateLoader(".", auto_reload=True)
52
63
        tmpl = loader.load(app_template)
53
64
        app = tmpl.generate(viewctx)
54
65
 
 
66
        for plugin in self.plugin_scripts:
 
67
            for path in self.plugin_scripts[plugin]:
 
68
                req.scripts.append(media_url(req, plugin, path))
 
69
 
 
70
        for plugin in self.plugin_styles:
 
71
            for path in self.plugin_styles[plugin]:
 
72
                req.styles.append(media_url(req, plugin, path))
 
73
 
55
74
        # Global template
56
75
        ctx = genshi.template.Context()
57
 
        ctx['app_styles'] = req.styles
58
 
        ctx['scripts'] = req.scripts
 
76
        # XXX: Leave this here!! (Before req.styles is read)
 
77
        ctx['overlays'] = self.render_overlays(req) if req.user else []
 
78
 
 
79
        ctx['styles'] = [media_url(req, CorePlugin, 'ivle.css')]
 
80
        ctx['styles'] += req.styles
 
81
 
 
82
        ctx['scripts'] = [media_url(req, CorePlugin, path) for path in
 
83
                           ('util.js', 'json2.js', 'md5.js')]
 
84
        ctx['scripts'] += req.scripts
 
85
 
59
86
        ctx['scripts_init'] = req.scripts_init
60
87
        ctx['app_template'] = app
 
88
        ctx['title_img'] = media_url(req, CorePlugin,
 
89
                                     "images/chrome/title.png")
61
90
        self.populate_headings(req, ctx)
62
91
        tmpl = loader.load(os.path.join(os.path.dirname(__file__), 
63
92
                                                        'ivle-headings.html'))
64
93
        req.write(tmpl.generate(ctx).render('xhtml', doctype='xhtml'))
 
94
        
 
95
    def populate(self, req, ctx):
 
96
        raise NotImplementedError()
65
97
 
66
98
    def populate_headings(self, req, ctx):
67
99
        ctx['favicon'] = None
74
106
            ctx['nick'] = req.user.nick
75
107
        else:
76
108
            ctx['login'] = None
 
109
            ctx['logged_in'] = False
77
110
        ctx['publicmode'] = req.publicmode
 
111
        if hasattr(self, 'help'):
 
112
            ctx['help_path'] = self.help
 
113
 
78
114
        ctx['apps_in_tabs'] = []
79
 
        for urlname in ivle.conf.apps.apps_in_tabs:
80
 
            new_app = {}
81
 
            app = ivle.conf.apps.app_url[urlname]
82
 
            new_app['this_app'] = hasattr(self, 'appname') \
83
 
                                  and urlname == self.appname
84
 
            if app.icon:
85
 
                new_app['has_icon'] = True
86
 
                icon_dir = ivle.conf.apps.app_icon_dir
87
 
                icon_url = ivle.util.make_path(os.path.join(icon_dir, app.icon))
88
 
                new_app['icon_url'] = icon_url
89
 
                if new_app['this_app']:
90
 
                    ctx['favicon'] = icon_url
 
115
        for plugin in req.config.plugin_index[ViewPlugin]:
 
116
            if not hasattr(plugin, 'tabs'):
 
117
                continue
 
118
 
 
119
            for tab in plugin.tabs:
 
120
                # tab is a tuple: name, title, desc, icon, path
 
121
                new_app = {}
 
122
                new_app['this_app'] = hasattr(self, 'tab') \
 
123
                                      and tab[0] == self.tab
 
124
 
 
125
                # Icon name
 
126
                if tab[3] is not None:
 
127
                    new_app['has_icon'] = True
 
128
                    icon_url = media_url(req, plugin, tab[3])
 
129
                    new_app['icon_url'] = icon_url
 
130
                    if new_app['this_app']:
 
131
                        ctx['favicon'] = icon_url
 
132
                else:
 
133
                    new_app['has_icon'] = False
 
134
                new_app['path'] = ivle.util.make_path(tab[4])
 
135
                new_app['desc'] = tab[2]
 
136
                new_app['name'] = tab[1]
 
137
                new_app['weight'] = tab[5]
 
138
                ctx['apps_in_tabs'].append(new_app)
 
139
 
 
140
        ctx['apps_in_tabs'].sort(key=lambda tab: tab['weight'])
 
141
 
 
142
    def render_overlays(self, req):
 
143
        """Generate XML streams for the overlays.
 
144
        
 
145
        Returns a list of streams. Populates the scripts, styles, and 
 
146
        scripts_init.
 
147
        """
 
148
        overlays = []
 
149
        if not self.allow_overlays:
 
150
            return overlays
 
151
 
 
152
        for plugin in req.config.plugin_index[OverlayPlugin]:
 
153
            for overclass in plugin.overlays:
 
154
                if overclass in self.overlay_blacklist:
 
155
                    continue
 
156
                overlay = overclass(req)
 
157
                #TODO: Re-factor this to look nicer
 
158
                for mplugin in overlay.plugin_scripts:
 
159
                    for path in overlay.plugin_scripts[mplugin]:
 
160
                        req.scripts.append(media_url(req, mplugin, path))
 
161
 
 
162
                for mplugin in overlay.plugin_styles:
 
163
                    for path in overlay.plugin_styles[mplugin]:
 
164
                        req.styles.append(media_url(req, mplugin, path))
 
165
 
 
166
                req.scripts_init += overlay.plugin_scripts_init
 
167
 
 
168
                overlays.append(overlay.render(req))
 
169
        return overlays
 
170
 
 
171
    @classmethod
 
172
    def get_error_view(cls, e):
 
173
        view_map = {HTTPError:    XHTMLErrorView,
 
174
                    Unauthorized: XHTMLUnauthorizedView}
 
175
        for exccls in inspect.getmro(type(e)):
 
176
            if exccls in view_map:
 
177
                return view_map[exccls]
 
178
 
 
179
class XHTMLErrorView(XHTMLView):
 
180
    template = 'xhtmlerror.html'
 
181
 
 
182
    def __init__(self, req, exception):
 
183
        self.context = exception
 
184
 
 
185
    def populate(self, req, ctx):
 
186
        ctx['exception'] = self.context
 
187
 
 
188
class XHTMLUnauthorizedView(XHTMLErrorView):
 
189
    template = 'xhtmlunauthorized.html'
 
190
 
 
191
    def __init__(self, req, exception):
 
192
        super(XHTMLUnauthorizedView, self).__init__(req, exception)
 
193
 
 
194
        if req.user is None:
 
195
            # Not logged in. Redirect to login page.
 
196
            if req.uri == '/':
 
197
                query_string = ''
91
198
            else:
92
 
                new_app['has_icon'] = False
93
 
            new_app['path'] = ivle.util.make_path(urlname)
94
 
            new_app['desc'] = app.desc
95
 
            new_app['name'] = app.name
96
 
            ctx['apps_in_tabs'].append(new_app)
 
199
                query_string = '?url=' + urllib.quote(req.uri, safe="/~")
 
200
            req.throw_redirect('/+login' + query_string)
 
201
 
 
202
        req.status = 403