[doc] add some documentation on url path evaulators
authorAdrien Di Mascio <Adrien.DiMascio@logilab.fr>
Fri, 28 Oct 2011 12:07:37 +0200
changeset 8039 1fe90d4ec307
parent 8038 678d22a56ab6
child 8041 81794aa0c8b4
[doc] add some documentation on url path evaulators
doc/book/en/devweb/views/urlpublish.rst
web/views/urlpublishing.py
--- a/doc/book/en/devweb/views/urlpublish.rst	Fri Oct 28 11:44:50 2011 +0200
+++ b/doc/book/en/devweb/views/urlpublish.rst	Fri Oct 28 12:07:37 2011 +0200
@@ -10,6 +10,70 @@
 .. autoclass:: cubicweb.web.views.urlpublishing.URLPublisherComponent
    :members:
 
+
+You can write your own *URLPathEvaluator* class to handle custom paths.
+For instance, if you want */my-card-id* to redirect to the corresponding
+card's primary view, you would write:
+
+.. sourcecode:: python
+
+    class CardWikiidEvaluator(URLPathEvaluator):
+        priority = 3 # make it be evaluated *before* RestPathEvaluator
+
+        def evaluate_path(self, req, segments):
+            if len(segments) != 1:
+                raise PathDontMatch()
+            rset = req.execute('Any C WHERE C wikiid %(w)s',
+                               {'w': segments[0]})
+            if len(rset) == 0:
+                # Raise NotFound if no card is found
+                raise PathDontMatch()
+            return None, rset
+
+On the other hand, you can also deactivate some of the standard
+evaluators in your final application. The only thing you have to
+do is to unregister them, for instance in a *registration_callback*
+in your cube:
+
+.. sourcecode:: python
+
+    def registration_callback(vreg):
+        vreg.unregister(RestPathEvaluator)
+
+You can even replace the :class:`cubicweb.web.views.urlpublishing.URLPublisherComponent`
+class if you want to customize the whole toolchain process or if you want
+to plug into an early enough extension point to control your request
+parameters:
+
+.. sourcecode:: python
+
+    class SanitizerPublisherComponent(URLPublisherComponent):
+        """override default publisher component to explicitly ignore
+        unauthorized request parameters in anonymous mode.
+        """
+        unauthorized_form_params = ('rql', 'vid', '__login', '__password')
+
+        def process(self, req, path):
+            if req.session.anonymous_session:
+                self._remove_unauthorized_params(req)
+            return super(SanitizerPublisherComponent, self).process(req, path)
+
+        def _remove_unauthorized_params(self, req):
+            for param in req.form.keys():
+                if param in self.unauthorized_form_params:
+                     req.form.pop(param)
+
+
+    def registration_callback(vreg):
+        vreg.register_and_replace(SanitizerPublisherComponent, URLPublisherComponent)
+
+
+.. autoclass:: cubicweb.web.views.urlpublishing.RawPathEvaluator
+.. autoclass:: cubicweb.web.views.urlpublishing.EidPathEvaluator
+.. autoclass:: cubicweb.web.views.urlpublishing.URLRewriteEvaluator
+.. autoclass:: cubicweb.web.views.urlpublishing.RestPathEvaluator
+.. autoclass:: cubicweb.web.views.urlpublishing.ActionPathEvaluator
+
 URL rewriting
 -------------
 
--- a/web/views/urlpublishing.py	Fri Oct 28 11:44:50 2011 +0200
+++ b/web/views/urlpublishing.py	Fri Oct 28 12:07:37 2011 +0200
@@ -17,21 +17,42 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """Associate url's path to view identifier / rql queries.
 
-It currently handles url path with the forms:
+CubicWeb finds all registered URLPathEvaluators, orders them according
+to their ``priority`` attribute and calls their ``evaluate_path()``
+method. The first that returns something and doesn't raise a
+``PathDontMatch`` exception wins.
+
+Here is the default evaluator chain:
 
-* <publishing_method>
-* minimal REST publishing:
+1. :class:`cubicweb.web.views.urlpublishing.RawPathEvaluator` handles
+   unique url segments that match exactly one of the registered
+   controller's *__regid__*. Urls such as */view?*, */edit?*, */json?*
+   fall in that category;
+
+2. :class:`cubicweb.web.views.urlpublishing.EidPathEvaluator` handles
+   unique url segments that are eids (e.g. */1234*);
 
-  * <eid>
-  * <etype>[/<attribute name>/<attribute value>]*
-* folder navigation
+3. :class:`cubicweb.web.views.urlpublishing.URLRewriteEvaluator`
+   selects all urlrewriter components, sorts them according to their
+   priorty, call their ``rewrite()`` method, the first one that
+   doesn't raise a ``KeyError`` wins. This is where the
+   :mod:`cubicweb.web.views.urlrewrite` and
+   :class:`cubicweb.web.views.urlrewrite.SimpleReqRewriter` comes into
+   play;
 
-You can actually control URL (more exactly path) resolution using an
-URL path evaluator.
+4. :class:`cubicweb.web.views.urlpublishing.RestPathEvaluator` handles
+   urls based on entity types and attributes : <etype>((/<attribute
+   name>])?/<attribute value>)?  This is why ``cwuser/carlos`` works;
+
+5. :class:`cubicweb.web.views.urlpublishing.ActionPathEvaluator`
+   handles any of the previous paths with an additional trailing
+   "/<action>" segment, <action> being one of the registered actions'
+   __regid__.
+
 
 .. note::
 
- Actionpath and Folderpath execute a query whose results is lost
+ Actionpath executes a query whose results is lost
  because of redirecting instead of direct traversal.
 """
 __docformat__ = "restructuredtext en"