[view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 10 Jun 2010 16:23:07 +0200
changeset 5715 2c3e83817a8e
parent 5714 04a8e48f10bc
child 5716 0e2af244dea5
[view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
selectors.py
view.py
web/component.py
web/controller.py
web/views/basecontrollers.py
web/views/embedding.py
--- a/selectors.py	Thu Jun 10 14:16:49 2010 +0200
+++ b/selectors.py	Thu Jun 10 16:23:07 2010 +0200
@@ -538,8 +538,8 @@
 @objectify_selector
 @lltrace
 def one_line_rset(cls, req, rset=None, row=None, **kwargs):
-    """Return 1 if the result set is of size 1 or if a specific row in the
-    result set is specified ('row' argument).
+    """Return 1 if the result set is of size 1, or greater but a specific row in
+      the result set is specified ('row' argument).
     """
     if rset is not None and (row is not None or rset.rowcount == 1):
         return 1
--- a/view.py	Thu Jun 10 14:16:49 2010 +0200
+++ b/view.py	Thu Jun 10 16:23:07 2010 +0200
@@ -366,6 +366,17 @@
     __select__ = non_final_entity()
     category = 'entityview'
 
+    def call(self, **kwargs):
+        if self.cw_rset is None:
+            self.entity_call(self.cw_extra_kwargs.pop('entity'))
+        else:
+            super(EntityView, self).call(**kwargs)
+
+    def cell_call(self, row, col, **kwargs):
+        self.entity_call(self.cw_rset.get_entity(row, col), **kwargs)
+
+    def entity_call(self, entity, **kwargs):
+        raise NotImplementedError()
 
 class StartupView(View):
     """base class for views which doesn't need a particular result set to be
--- a/web/component.py	Thu Jun 10 14:16:49 2010 +0200
+++ b/web/component.py	Thu Jun 10 16:23:07 2010 +0200
@@ -15,9 +15,10 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""abstract component class and base components definition for CubicWeb web client
+"""abstract component class and base components definition for CubicWeb web
+client
+"""
 
-"""
 __docformat__ = "restructuredtext en"
 _ = unicode
 
@@ -61,9 +62,15 @@
     context = 'navcontentbottom'
 
     def call(self, view=None):
-        return self.cell_call(0, 0, view=view)
+        if self.cw_rset is None:
+            self.entity_call(self.cw_extra_kwargs.pop('entity'))
+        else:
+            self.cell_call(0, 0, view=view)
 
     def cell_call(self, row, col, view=None):
+        self.entity_call(self.cw_rset.get_entity(row, col), view=view)
+
+    def entity_call(self, entity, view=None):
         raise NotImplementedError()
 
 
--- a/web/controller.py	Thu Jun 10 14:16:49 2010 +0200
+++ b/web/controller.py	Thu Jun 10 16:23:07 2010 +0200
@@ -82,18 +82,20 @@
 
     # generic methods useful for concrete implementations ######################
 
-    def process_rql(self, rql):
+    def process_rql(self):
         """execute rql if specified"""
-        # XXX assigning to self really necessary?
-        self.cw_rset = None
+        req = self._cw
+        rql = req.form.get('rql')
         if rql:
-            self._cw.ensure_ro_rql(rql)
+            req.ensure_ro_rql(rql)
             if not isinstance(rql, unicode):
-                rql = unicode(rql, self._cw.encoding)
-            pp = self._cw.vreg['components'].select_or_none('magicsearch', self._cw)
+                rql = unicode(rql, req.encoding)
+            pp = req.vreg['components'].select_or_none('magicsearch', req)
             if pp is not None:
-                self.cw_rset = pp.process_query(rql)
-        return self.cw_rset
+                return pp.process_query(rql)
+        if 'eid' in req.form:
+            return req.eid_rset(req.form['eid'])
+        return None
 
     def notify_edited(self, entity):
         """called by edit_entity() to notify which entity is edited"""
--- a/web/views/basecontrollers.py	Thu Jun 10 14:16:49 2010 +0200
+++ b/web/views/basecontrollers.py	Thu Jun 10 16:23:07 2010 +0200
@@ -128,7 +128,7 @@
         if rset is None and not hasattr(req, '_rql_processed'):
             req._rql_processed = True
             if req.cnx:
-                rset = self.process_rql(req.form.get('rql'))
+                rset = self.process_rql()
             else:
                 rset = None
         if rset and rset.rowcount == 1 and '__method' in req.form:
@@ -378,6 +378,8 @@
         rql = req.form.get('rql')
         if rql:
             rset = self._exec(rql)
+        elif 'eid' in req.form:
+            rset = self._cw.eid_rset(req.form['eid'])
         else:
             rset = None
         vid = req.form.get('vid') or vid_from_rset(req, rset, self._cw.vreg.schema)
--- a/web/views/embedding.py	Thu Jun 10 14:16:49 2010 +0200
+++ b/web/views/embedding.py	Thu Jun 10 16:23:07 2010 +0200
@@ -94,9 +94,9 @@
             except HTTPError, err:
                 body = '<h2>%s</h2><h3>%s</h3>' % (
                     _('error while embedding page'), err)
-        self.process_rql(req.form.get('rql'))
+        rset = self.process_rql()
         return self._cw.vreg['views'].main_template(req, self.template,
-                                                rset=self.cw_rset, body=body)
+                                                    rset=rset, body=body)
 
 
 def entity_has_embedable_url(entity):