web/views/basetemplates.py
branchtls-sprint
changeset 823 cb8ccbef8fa5
parent 822 e3d8db01f3f5
child 826 51cb3d85c059
--- a/web/views/basetemplates.py	Wed Feb 18 18:06:41 2009 +0100
+++ b/web/views/basetemplates.py	Wed Feb 18 19:19:57 2009 +0100
@@ -11,10 +11,10 @@
 from logilab.mtconverter import html_escape
 
 from cubicweb import NoSelectableObject, ObjectNotFound
+from cubicweb.vregistry import objectify_selector
 from cubicweb.selectors import match_kwargs
 from cubicweb.view import View, MainTemplate,  NOINDEX, NOFOLLOW
 from cubicweb.utils import make_uid, UStringIO
-from cubicweb.web.views.baseviews import vid_from_rset
 
 # main templates ##############################################################
 
@@ -64,89 +64,67 @@
                 html_escape(indexurl),
                 self.req._('go back to the index page')))
 
+@objectify_selector
+def templatable_view(cls, req, rset, *args, **kwargs):
+    view = kwargs.pop('view', None)
+    if view is None:
+        return 1
+    if view.binary:
+        return 0
+    if req.form.has_key('__notemplate'):
+        return 0
+    return view.templatable
+
+@objectify_selector
+def non_templatable_view(cls, req, rset, *args, **kwargs):
+    return not templatable_view()(cls, req, rset, *args, **kwargs)
+
+
+class NonTemplatableViewTemplate(MainTemplate):
+    """main template for any non templatable views (xml, binaries, etc.)"""
+    id = 'main-template'
+    __select__ = non_templatable_view()
+    
+    def call(self, view):
+        view.set_request_content_type()
+        self.set_stream(templatable=False)
+        # have to replace our unicode stream using view's binary stream
+        view.dispatch()
+        assert self._stream, 'duh, template used as a sub-view ?? (%s)' % self._stream
+        self._stream = view._stream
+
 
 class TheMainTemplate(MainTemplate):
     """default main template :
 
     - call header / footer templates
-    - build result set
-    - guess and call an appropriate view through the view manager
     """
-    id = 'main'
-
-    def _select_view_and_rset(self):
-        req = self.req
-        if self.rset is None and not hasattr(req, '_rql_processed'):
-            req._rql_processed = True
-            rset = self.process_rql(req.form.get('rql'))
-        else:
-            rset = self.rset
-        # handle special "method" param when necessary
-        # XXX this should probably not be in the template (controller ?), however:
-        #     * we need to have the displayed rset
-        #     * we don't want to handle it in each view
-        if rset and rset.rowcount == 1 and '__method' in req.form:
-            entity = rset.get_entity(0, 0)
-            try:
-                method = getattr(entity, req.form.pop('__method'))
-                method()
-            except Exception, ex:
-                self.exception('while handling __method')
-                req.set_message(req._("error while handling __method: %s") % req._(ex))
-        vid = req.form.get('vid') or vid_from_rset(req, rset, self.schema)
-        try:
-            view = self.vreg.select_view(vid, req, rset)
-        except ObjectNotFound:
-            self.warning("the view %s could not be found", vid)
-            req.set_message(req._("The view %s could not be found") % vid)
-            vid = vid_from_rset(req, rset, self.schema)
-            view = self.vreg.select_view(vid, req, rset)
-        except NoSelectableObject:
-            if rset:
-                req.set_message(req._("The view %s can not be applied to this query") % vid)
-            else:
-                req.set_message(req._("You have no access to this view or it's not applyable to current data"))
-            self.warning("the view %s can not be applied to this query", vid)
-            vid = vid_from_rset(req, rset, self.schema)
-            view = self.vreg.select_view(vid, req, rset)
-        return view, rset
-
-    def call(self):
-        view, rset = self._select_view_and_rset()
-        req = self.req
-        # update breadcrumps **before** validating cache, unless the view
-        # specifies explicitly it should not be added to breadcrumb or the
-        # view is a binary view
-        if view.add_to_breadcrumbs and not view.binary:
-            req.update_breadcrumbs()
-        view.set_http_cache_headers()
-        req.validate_cache()
-        with_templates = self.with_templates(view)
-        if with_templates:
-            self.set_request_content_type()
-            content_type = self.content_type
-            self.template_header(content_type, view)
-        else:
-            view.set_request_content_type()
-            self.set_stream(templatable=False)
-        self.wview('page-content', view=view, rset=rset)
-        if with_templates:
-            self.template_footer(view)
-
-    def with_templates(self, view):
-        return (not view.binary and view.templatable and
-                not self.req.form.has_key('__notemplate'))
-
-    def process_rql(self, rql):
-        """execute rql if specified"""
-        if rql:
-            self.ensure_ro_rql(rql)
-            if not isinstance(rql, unicode):
-                rql = unicode(rql, self.req.encoding)
-            pp = self.vreg.select_component('magicsearch', self.req)
-            self.rset = pp.process_query(rql, self.req)
-            return self.rset
-        return None
+    id = 'main-template'
+    __select__ = templatable_view()
+    
+    def call(self, view):
+        self.set_request_content_type()
+        self.template_header(self.content_type, view)
+        w = self.w
+        w(u'<div id="pageContent">\n')
+        vtitle = self.req.form.get('vtitle')
+        if vtitle:
+            w(u'<h1 class="vtitle">%s</h1>\n' % html_escape(vtitle))
+        # display entity type restriction component
+        etypefilter = self.vreg.select_component('etypenavigation',
+                                                 self.req, self.rset)
+        if etypefilter and etypefilter.propval('visible'):
+            etypefilter.dispatch(w=w)
+        self.nav_html = UStringIO()
+        self.pagination(self.req, self.rset, self.nav_html.write,
+                        not (view and view.need_navigation))
+        w(_(self.nav_html.getvalue()))
+        w(u'<div id="contentmain">\n')
+        view.dispatch(w=w)
+        w(u'</div>\n') # close id=contentmain
+        w(_(self.nav_html.getvalue()))
+        w(u'</div>\n') # closes id=pageContent
+        self.template_footer(view)
 
     def template_header(self, content_type, view=None, page_title='', additional_headers=()):
         page_title = page_title or view.page_title()
@@ -206,44 +184,6 @@
         self.wview('contentfooter', rset=self.rset, view=view)
 
 
-class PageContentTemplate(TheMainTemplate):
-    id = 'page-content'
-
-    def call(self, view=None, rset=None):
-        if view is None:
-            view, rset = self._select_view_and_rset()
-        with_templates = self.with_templates(view)
-        w = self.w
-        if with_templates:
-            w(u'<div id="pageContent">\n')
-            vtitle = self.req.form.get('vtitle')
-            if vtitle:
-                w(u'<h1 class="vtitle">%s</h1>\n' % html_escape(vtitle))
-            # display entity type restriction component
-            etypefilter = self.vreg.select_component('etypenavigation',
-                                                     self.req, self.rset)
-            if etypefilter and etypefilter.propval('visible'):
-                etypefilter.dispatch(w=w)
-            self.nav_html = UStringIO()
-            self.pagination(self.req, self.rset, self.nav_html.write,
-                            not (view and view.need_navigation))
-            w(_(self.nav_html.getvalue()))
-            w(u'<div id="contentmain">\n')
-        else:
-            self.set_stream(templatable=False)            
-        if view.binary:
-            # have to replace our unicode stream using view's binary stream
-            view.dispatch()
-            assert self._stream, 'duh, template used as a sub-view ?? (%s)' % self._stream
-            self._stream = view._stream
-        else:
-            view.dispatch(w=w)
-        if with_templates:
-            w(u'</div>\n') # close id=contentmain
-            w(_(self.nav_html.getvalue()))
-            w(u'</div>\n') # closes id=pageContent
-
-
 class ErrorTemplate(TheMainTemplate):
     """fallback template if an internal error occured during displaying the
     main template. This template may be called for authentication error,
@@ -534,3 +474,7 @@
         return req.url().replace(req.base_url(), config['https-url'])
     return req.url()
 
+
+## vregistry registration callback ############################################
+def registration_callback(vreg):
+    vreg.register_all(globals().values(), modname=__name__)