doc type handling refactoring: do the ext substitution at the module level tls-sprint
authorsylvain.thenault@logilab.fr
Wed, 22 Apr 2009 16:54:23 +0200
branchtls-sprint
changeset 1421 77ee26df178f
parent 1420 25c13e5b12bd
child 1422 51b3fd55784e
doc type handling refactoring: do the ext substitution at the module level
devtools/htmlparser.py
view.py
web/request.py
web/views/basetemplates.py
--- a/devtools/htmlparser.py	Wed Apr 22 16:51:29 2009 +0200
+++ b/devtools/htmlparser.py	Wed Apr 22 16:54:23 2009 +0200
@@ -4,10 +4,7 @@
 
 from lxml import etree
 
-from cubicweb.view import STRICT_DOCTYPE, TRANSITIONAL_DOCTYPE, CW_XHTML_EXTENSIONS
-
-STRICT_DOCTYPE = str(STRICT_DOCTYPE % CW_XHTML_EXTENSIONS).strip()
-TRANSITIONAL_DOCTYPE = str(TRANSITIONAL_DOCTYPE % CW_XHTML_EXTENSIONS).strip()
+from cubicweb.view import STRICT_DOCTYPE, TRANSITIONAL_DOCTYPE
 
 ERR_COUNT = 0
 
--- a/view.py	Wed Apr 22 16:51:29 2009 +0200
+++ b/view.py	Wed Apr 22 16:54:23 2009 +0200
@@ -66,9 +66,10 @@
  cubicweb:facetName         CDATA   #IMPLIED
   "> ] '''
 
-TRANSITIONAL_DOCTYPE = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" %s>\n'
-
-STRICT_DOCTYPE = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" %s>\n'
+TRANSITIONAL_DOCTYPE = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" %s>\n' % CW_XHTML_EXTENSIONS
+TRANSITIONAL_DOCTYPE_NOEXT = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n'
+STRICT_DOCTYPE = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" %s>\n' % CW_XHTML_EXTENSIONS
+STRICT_DOCTYPE_NOEXT = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
 
 # base view object ############################################################
 
@@ -108,9 +109,7 @@
 
     @property
     def content_type(self):
-        if self.req.xhtml_browser():
-            return 'application/xhtml+xml'
-        return 'text/html'
+        return self.req.html_content_type()
 
     def set_stream(self, w=None):
         if self.w is not None:
@@ -419,14 +418,13 @@
     There is usually at least a regular main template and a simple fallback
     one to display error if the first one failed
     """
-    base_doctype = STRICT_DOCTYPE
     registered = require_group_compat(View.registered)
 
     @property
     def doctype(self):
         if self.req.xhtml_browser():
-            return self.base_doctype % CW_XHTML_EXTENSIONS
-        return self.base_doctype % ''
+            return STRICT_DOCTYPE
+        return STRICT_DOCTYPE_NOEXT
 
     def set_stream(self, w=None, templatable=True):
         if templatable and self.w is not None:
--- a/web/request.py	Wed Apr 22 16:51:29 2009 +0200
+++ b/web/request.py	Wed Apr 22 16:54:23 2009 +0200
@@ -56,8 +56,8 @@
 
 
 class CubicWebRequestBase(DBAPIRequest):
-    """abstract HTTP request, should be extended according to the HTTP backend"""    
-    
+    """abstract HTTP request, should be extended according to the HTTP backend"""
+
     def __init__(self, vreg, https, form=None):
         super(CubicWebRequestBase, self).__init__(vreg)
         self.message = None
@@ -657,13 +657,18 @@
     
     def xhtml_browser(self):
         useragent = self.useragent()
-        # MSIE does not support xml content-type
-        # quick fix: Opera supports xhtml and handles namespaces
-        # properly but it breaks jQuery.attr()
+        # * MSIE/Konqueror does not support xml content-type
+        # * Opera supports xhtml and handles namespaces properly but it breaks
+        #   jQuery.attr()
         if useragent and ('MSIE' in useragent or 'KHTML' in useragent
                           or 'Opera' in useragent):
             return False
         return True
 
+    def html_content_type(self):
+        if self.xhtml_browser():
+            return 'application/xhtml+xml'
+        return 'text/html'
+
 from cubicweb import set_log_methods
 set_log_methods(CubicWebRequestBase, LOGGER)
--- a/web/views/basetemplates.py	Wed Apr 22 16:51:29 2009 +0200
+++ b/web/views/basetemplates.py	Wed Apr 22 16:54:23 2009 +0200
@@ -12,7 +12,7 @@
 
 from cubicweb.vregistry import objectify_selector
 from cubicweb.selectors import match_kwargs
-from cubicweb.view import View, MainTemplate,  NOINDEX, NOFOLLOW
+from cubicweb.view import View, MainTemplate,  NOINDEX, NOFOLLOW, STRICT_DOCTYPE
 from cubicweb.utils import make_uid, UStringIO
 
 # main templates ##############################################################
@@ -78,14 +78,20 @@
 class NonTemplatableViewTemplate(MainTemplate):
     """main template for any non templatable views (xml, binaries, etc.)"""
     id = 'main-template'
-    __select__ = ~ templatable_view()
-    
+    __select__ = ~templatable_view()
+
     def call(self, view):
         view.set_request_content_type()
-        self.set_stream(templatable=False)
+        view.set_stream()
+        xhtml_wrap = (self.req.form.has_key('__notemplate') and view.templatable
+                      and view.content_type == self.req.html_content_type())
+        if xhtml_wrap:
+            view.w(u'<?xml version="1.0"?>\n' + STRICT_DOCTYPE)
+            view.w(u'<div xmlns="http://www.w3.org/1999/xhtml" xmlns:cubicweb="http://www.logilab.org/2008/cubicweb">')
         # 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
+        if xhtml_wrap:
+            view.w(u'</div>')
         self._stream = view._stream
 
 
@@ -96,7 +102,7 @@
     """
     id = 'main-template'
     __select__ = templatable_view()
-    
+
     def call(self, view):
         self.set_request_content_type()
         self.template_header(self.content_type, view)
@@ -417,9 +423,9 @@
 class LogFormTemplate(View):
     id = 'logform'
     __select__ = match_kwargs('id', 'klass')
-    
+
     title = 'log in'
-    
+
     def call(self, id, klass, title=True, message=True):
         self.req.add_css('cubicweb.login.css')
         self.w(u'<div id="%s" class="%s">' % (id, klass))