merge tls-sprint
authorsylvain.thenault@logilab.fr
Mon, 16 Feb 2009 20:51:41 +0100
branchtls-sprint
changeset 644 5e5b296a657e
parent 640 8e64f12be69c (current diff)
parent 643 616191014b8b (diff)
child 646 8a9551089912
merge
web/views/basecontrollers.py
--- a/common/utils.py	Mon Feb 16 20:51:24 2009 +0100
+++ b/common/utils.py	Mon Feb 16 20:51:41 2009 +0100
@@ -177,7 +177,7 @@
             self.post_inlined_scripts.append(self.js_unload_code)
             self.pagedata_unload = True
 
-    def getvalue(self):
+    def getvalue(self, skiphead=False):
         """reimplement getvalue to provide a consistent (and somewhat browser
         optimzed cf. http://stevesouders.com/cuzillion) order in external
         resources declaration
@@ -209,7 +209,10 @@
             w(u'<script type="text/javascript">\n')
             w(u'\n\n'.join(self.post_inlined_scripts))
             w(u'\n</script>\n')
-        return u'<head>\n%s</head>\n' % super(HTMLHead, self).getvalue()
+        header = super(HTMLHead, self).getvalue()
+        if skiphead:
+            return header
+        return u'<head>\n%s</head>\n' % header
         
 
 class HTMLStream(object):
--- a/web/data/cubicweb.ajax.js	Mon Feb 16 20:51:24 2009 +0100
+++ b/web/data/cubicweb.ajax.js	Mon Feb 16 20:51:41 2009 +0100
@@ -9,7 +9,18 @@
 
 var JSON_BASE_URL = baseuri() + 'json?';
 
-function postAjaxLoad(node) {
+/*
+ * inspect dom response, search for a <div class="ajaxHtmlHead"> node and
+ * put its content into the real document's head.
+ * This enables dynamic css and js loading and is used by replacePageChunk
+ */
+function loadAjaxHtmlHead(node) {
+    jQuery(node).find('div.ajaxHtmlHead').appendTo(jQuery('head'));
+}
+
+function postAjaxLoad(node, req) {
+    // addStylesheets(evalJSON(req.getResponseHeader('X-Cubicweb-Stylesheets') || '[]'));
+    loadAjaxHtmlHead(node);
     // find sortable tables if there are some
     if (typeof(Sortable) != 'undefined') {
 	Sortable.sortTables(node);
@@ -28,23 +39,18 @@
 
 // cubicweb loadxhtml plugin to make jquery handle xhtml response
 jQuery.fn.loadxhtml = function(url, data, reqtype, mode) {
-    var ajax = null;
-    if (reqtype == 'post') {
-	ajax = jQuery.post;
-    } else {
-	ajax = jQuery.get;
-    }
     if (this.size() > 1) {
 	log('loadxhtml was called with more than one element');
     }
+    var node = this.get(0); // only consider the first element
     mode = mode || 'replace';
     var callback = null;
     if (data && data.callback) {
 	callback = data.callback;
 	delete data.callback;
     }
-    var node = this.get(0); // only consider the first element
-    ajax(url, data, function(response) {
+    var deferred = loadJSON(url, data, reqtype);
+    deferred.addCallback(function(response, req) {
 	var domnode = getDomFromResponse(response);
 	if (mode == 'swap') {
 	    var origId = node.id;
@@ -57,7 +63,7 @@
 	} else if (mode == 'append') {
 	    jQuery(node).append(domnode);
 	}
-	postAjaxLoad(node);
+	postAjaxLoad(node, req);
 	while (jQuery.isFunction(callback)) {
 	    callback = callback.apply(this, [domnode]);
 	}
--- a/web/views/basecontrollers.py	Mon Feb 16 20:51:24 2009 +0100
+++ b/web/views/basecontrollers.py	Mon Feb 16 20:51:41 2009 +0100
@@ -211,14 +211,14 @@
             self.req.set_content_type(content_type)
             return xmlize(data)
         return data
-
+    
     def html_exec(self, rset=None):
-        """html mode: execute query and return the view as HTML"""
+        # XXX try to use the page-content template
         req = self.req
         rql = req.form.get('rql')
         if rset is None and rql:
             rset = self._exec(rql)
-            
+        
         vid = req.form.get('vid') or vid_from_rset(req, rset, self.schema)
         try:
             view = self.vreg.select_view(vid, req, rset)
@@ -239,6 +239,10 @@
             if divid == 'pageContent':
                 stream.write(u'<div id="contentmain">')
         view.dispatch()
+        extresources = req.html_headers.getvalue(skiphead=True)
+        stream.write(u'<div class="ajaxHtmlHead">\n') # XXX use a widget ?
+        stream.write(extresources)
+        stream.write(u'</div>\n')
         if req.form.get('paginate') and divid == 'pageContent':
             stream.write(u'</div></div>')
         source = stream.getvalue()
--- a/web/views/basetemplates.py	Mon Feb 16 20:51:24 2009 +0100
+++ b/web/views/basetemplates.py	Mon Feb 16 20:51:41 2009 +0100
@@ -19,9 +19,8 @@
 
 # main templates ##############################################################
 
+class LogInOutTemplate(MainTemplate):
 
-class LogInOutTemplate(MainTemplate):
-    
     def call(self):
         self.set_request_content_type()
         w = self.w
@@ -43,7 +42,7 @@
         w(u'\n'.join(additional_headers) + u'\n')
         self.template('htmlheader', rset=self.rset)
         w(u'<title>%s</title>\n' % html_escape(page_title))
-        
+
 
 class LogInTemplate(LogInOutTemplate):
     id = 'login'
@@ -51,7 +50,7 @@
 
     def content(self, w):
         self.template('logform', rset=self.rset, id='loginBox', klass='')
-        
+
 
 class LoggedOutTemplate(LogInOutTemplate):
     id = 'loggedout'
@@ -66,10 +65,10 @@
                 html_escape(indexurl),
                 self.req._('go back to the index page')))
 
-        
+
 class TheMainTemplate(MainTemplate):
     """default main template :
-    
+
     - call header / footer templates
     - build result set
     - guess and call an appropriate view through the view manager
@@ -112,7 +111,7 @@
             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
@@ -123,8 +122,7 @@
             req.update_breadcrumbs()
         view.set_http_cache_headers()
         req.validate_cache()
-        with_templates = not view.binary and view.templatable and \
-                         not req.form.has_key('__notemplate')
+        with_templates = self.with_templates(view)
         if not with_templates:
             view.set_request_content_type()
             self.set_stream(templatable=False)
@@ -132,17 +130,14 @@
             self.set_request_content_type()
             content_type = self.content_type
             self.template_header(content_type, view)
-        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=self.w)
+        self.template('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:
@@ -159,17 +154,7 @@
         additional_headers = additional_headers or view.html_headers()
         self.template_html_header(content_type, page_title, additional_headers)
         self.template_body_header(view)
-        # display entity type restriction component
-        etypefilter = self.vreg.select_component('etypenavigation',
-                                                 self.req, self.rset)
-        if etypefilter and etypefilter.propval('visible'):
-            etypefilter.dispatch(w=self.w)
-        self.nav_html = UStringIO()
-        self.pagination(self.req, self.rset, self.nav_html.write,
-                        not (view and view.need_navigation))
-        self.w(_(self.nav_html.getvalue()))
-        self.w(u'<div id="contentmain">\n')
-    
+
     def template_html_header(self, content_type, page_title, additional_headers=()):
         w = self.whead
         lang = self.req.lang
@@ -196,15 +181,8 @@
         if msgcomp:
             msgcomp.dispatch(w=self.w)
         self.content_header(view)
-        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))
-            
+
     def template_footer(self, view=None):
-        self.w(u'</div>\n') # close id=contentmain
-        self.w(_(self.nav_html.getvalue()))
-        self.w(u'</div>\n') # closes id=pageContent
         self.content_footer(view)
         self.w(u'</td>\n')
         self.nav_column(view, 'right')
@@ -224,18 +202,55 @@
     def content_header(self, view=None):
         """by default, display informal messages in content header"""
         self.template('contentheader', rset=self.rset, view=view)
-            
+
     def content_footer(self, view=None):
         self.template('contentfooter', rset=self.rset, view=view)
 
 
+class PageContentTemplate(TheMainTemplate):
+    id = 'page-content'
+
+    def call(self, view=None, rset=None):
+        self.req.set_header('x-cubicweb-css', 'a.css;b.css')
+        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')
+        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,
     which means that req.cnx and req.user may not be set.
     """
     id = 'error'
-    
+
     def call(self):
         """display an unexpected error"""
         self.set_request_content_type()
@@ -245,7 +260,7 @@
                              [NOINDEX, NOFOLLOW])
         view.dispatch(w=self.w)
         self.template_footer(view)
-    
+
     def template_header(self, content_type, view=None, page_title='', additional_headers=()):
         w = self.whead
         lang = self.req.lang
@@ -264,7 +279,7 @@
 class SimpleMainTemplate(TheMainTemplate):
 
     id = 'main-no-top'
-    
+
     def template_header(self, content_type, view=None, page_title='', additional_headers=()):
         page_title = page_title or view.page_title()
         additional_headers = additional_headers or view.html_headers()
@@ -295,7 +310,7 @@
         vtitle = self.req.form.get('vtitle')
         if vtitle:
             w(u'<h1 class="vtitle">%s</h1>' % html_escape(vtitle))
-            
+
     def topleft_header(self):
         self.w(u'<table id="header"><tr>\n')
         self.w(u'<td>')
@@ -308,7 +323,7 @@
 class HTMLHeader(Template):
     """default html headers"""
     id = 'htmlheader'
-    
+
     def call(self, **kwargs):
         self.favicon()
         self.stylesheets()
@@ -320,7 +335,7 @@
         favicon = self.req.external_resource('FAVICON', None)
         if favicon:
             self.whead(u'<link rel="shortcut icon" href="%s"/>\n' % favicon)
-            
+
     def stylesheets(self):
         req = self.req
         add_css = req.add_css
@@ -330,11 +345,11 @@
             add_css(css, u'print', localfile=False)
         for css in req.external_resource('IE_STYLESHEETS'):
             add_css(css, localfile=False, ieonly=True)
-        
+
     def javascripts(self):
         for jscript in self.req.external_resource('JAVASCRIPTS'):
             self.req.add_js(jscript, localfile=False)
-            
+
     def alternates(self):
         urlgetter = self.vreg.select_component('rss_feed_url', self.req, self.rset)
         if urlgetter is not None:
@@ -352,7 +367,7 @@
 class HTMLPageHeader(Template):
     """default html page header"""
     id = 'header'
-    
+
     def call(self, view, **kwargs):
         self.main_header(view)
         self.w(u'''
@@ -361,7 +376,7 @@
         self.w(u'''
   </div>
   ''')
-        
+
     def main_header(self, view):
         """build the top menu with authentification info and the rql box"""
         self.w(u'<table id="header"><tr>\n')
@@ -392,7 +407,7 @@
         self.w(u'</tr></table>\n')
         self.template('logform', rset=self.rset, id='popupLoginBox', klass='hidden',
                       title=False, message=False)
-        
+
     def state_header(self):
         state = self.req.search_state
         if state[0] == 'normal':
@@ -402,7 +417,7 @@
         msg = ' '.join((_("searching for"),
                         display_name(self.req, state[1][3]),
                         _("to associate with"), value,
-                        _("by relation"), '"', 
+                        _("by relation"), '"',
                         display_name(self.req, state[1][2], state[1][0]),
                         '"'))
         return self.w(u'<div class="stateMessage">%s</div>' % msg)
@@ -413,7 +428,7 @@
     """default html page footer: include logo if any, and close the HTML body
     """
     id = 'footer'
-    
+
     def call(self, **kwargs):
         req = self.req
         self.w(u'<div class="footer">')
@@ -434,7 +449,7 @@
     * include selectable content navigation components
     """
     id = 'contentheader'
-    
+
     def call(self, view, **kwargs):
         """by default, display informal messages in content header"""
         components = self.vreg.possible_vobjects('contentnavigation',
@@ -452,7 +467,7 @@
     components
     """
     id = 'contentfooter'
-    
+
     def call(self, view, **kwargs):
         components = self.vreg.possible_vobjects('contentnavigation',
                                                  self.req, self.rset,
@@ -474,7 +489,7 @@
         if title:
             self.w(u'<div id="loginTitle">%s</div>'
                    % self.req.property_value('ui.site-title'))
-        self.w(u'<div id="loginContent">\n')        
+        self.w(u'<div id="loginContent">\n')
 
         if message:
             self.display_message()
@@ -490,7 +505,7 @@
         message = self.req.message
         if message:
             self.w(u'<div class="simpleMessage">%s</div>\n' % message)
-                     
+
     def login_form(self, id):
         _ = self.req._
         self.w(u'<form method="post" action="%s" id="login_form">\n'
@@ -509,7 +524,7 @@
         self.w(u'</form>\n')
         self.req.html_headers.add_onload('jQuery("#__login:visible").focus()')
 
-    
+
 def login_form_url(config, req):
     if req.https:
         return req.url()