# HG changeset patch
# User sylvain.thenault@logilab.fr
# Date 1234813901 -3600
# Node ID 5e5b296a657ee4da85002d7fbe2cb146c8ba9178
# Parent 8e64f12be69c9b7faada1e2aeaad48c24874ca2f# Parent 616191014b8b2998f3d73afe4946c0ca21319c92
merge
diff -r 8e64f12be69c -r 5e5b296a657e common/utils.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'\n')
- return u'
\n%s\n' % super(HTMLHead, self).getvalue()
+ header = super(HTMLHead, self).getvalue()
+ if skiphead:
+ return header
+ return u'\n%s\n' % header
class HTMLStream(object):
diff -r 8e64f12be69c -r 5e5b296a657e web/data/cubicweb.ajax.js
--- 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 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]);
}
diff -r 8e64f12be69c -r 5e5b296a657e web/views/basecontrollers.py
--- 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'
')
view.dispatch()
+ extresources = req.html_headers.getvalue(skiphead=True)
+ stream.write(u'
\n') # XXX use a widget ?
+ stream.write(extresources)
+ stream.write(u'
\n')
if req.form.get('paginate') and divid == 'pageContent':
stream.write(u'
')
source = stream.getvalue()
diff -r 8e64f12be69c -r 5e5b296a657e web/views/basetemplates.py
--- 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'\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'
\n')
- vtitle = self.req.form.get('vtitle')
- if vtitle:
- w(u'
%s
\n' % html_escape(vtitle))
-
+
def template_footer(self, view=None):
- self.w(u'\n') # close id=contentmain
- self.w(_(self.nav_html.getvalue()))
- self.w(u'
\n') # closes id=pageContent
self.content_footer(view)
self.w(u'\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'\n')
+ vtitle = self.req.form.get('vtitle')
+ if vtitle:
+ w(u'
%s
\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'
\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'
\n') # close id=contentmain
+ w(_(self.nav_html.getvalue()))
+ w(u'
\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'