1 """associate url's path to view identifier / rql queries |
1 # organization: Logilab |
2 |
2 # copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2. |
3 It currently handle url's path with the forms |
3 # contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
4 # license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
|
5 """Associate url's path to view identifier / rql queries. |
|
6 |
|
7 It currently handles url path with the forms: |
4 |
8 |
5 * <publishing_method> |
9 * <publishing_method> |
6 |
|
7 * minimal REST publishing: |
10 * minimal REST publishing: |
|
11 |
8 * <eid> |
12 * <eid> |
9 * <etype>[/<attribute name>/<attribute value>]* |
13 * <etype>[/<attribute name>/<attribute value>]* |
10 |
|
11 * folder navigation |
14 * folder navigation |
12 |
15 |
13 |
16 You can actually control URL (more exactly path) resolution using an |
14 You can actually control URL (more exactly path) resolution using URL path |
17 URL path evaluator. |
15 evaluator. |
18 |
16 |
19 .. note:: |
17 XXX actionpath and folderpath execute a query whose results is lost |
20 |
18 because of redirecting instead of direct traversal |
21 Actionpath and Folderpath execute a query whose results is lost |
19 |
22 because of redirecting instead of direct traversal. |
20 :organization: Logilab |
|
21 :copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2. |
|
22 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
23 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
|
24 """ |
23 """ |
25 |
|
26 __docformat__ = "restructuredtext en" |
24 __docformat__ = "restructuredtext en" |
27 |
25 |
28 from rql import TypeResolverException |
26 from rql import TypeResolverException |
29 |
27 |
30 from cubicweb import RegistryException, typed_eid |
28 from cubicweb import RegistryException, typed_eid |
35 """exception used by url evaluators to notify they can't evaluate |
33 """exception used by url evaluators to notify they can't evaluate |
36 a path |
34 a path |
37 """ |
35 """ |
38 |
36 |
39 class URLPublisherComponent(component.Component): |
37 class URLPublisherComponent(component.Component): |
40 """associate url's path to view identifier / rql queries, |
38 """Associate url path to view identifier / rql queries, by |
41 by applying a chain of urlpathevaluator components. |
39 applying a chain of urlpathevaluator components. |
42 |
40 |
43 An evaluator is a URLPathEvaluator subclass with a .evaluate_path |
41 An evaluator is a URLPathEvaluator subclass with an .evaluate_path |
44 method taking the request object and the path to publish as |
42 method taking the request object and the path to publish as |
45 argument. It will either returns a publishing method identifier |
43 argument. It will either return a publishing method identifier |
46 and a rql query on success or raises a `PathDontMatch` exception |
44 and an rql query on success or raise a `PathDontMatch` exception |
47 on failure. URL evaluators are called according to their `priority` |
45 on failure. URL evaluators are called according to their |
48 attribute, with 0 as the greatest priority and greater values as |
46 `priority` attribute, with 0 as the greatest priority and greater |
49 lower priority. The first evaluator returning a result or raising |
47 values as lower priority. The first evaluator returning a result |
50 something else than `PathDontMatch` will stop the handlers chain. |
48 or raising something else than `PathDontMatch` will stop the |
|
49 handlers chain. |
51 """ |
50 """ |
52 __regid__ = 'urlpublisher' |
51 __regid__ = 'urlpublisher' |
53 vreg = None # XXX necessary until property for deprecation warning is on appobject |
52 vreg = None # XXX necessary until property for deprecation warning is on appobject |
54 |
53 |
55 def __init__(self, vreg, default_method='view'): |
54 def __init__(self, vreg, default_method='view'): |
62 evaluator = evaluatorcls(self) |
61 evaluator = evaluatorcls(self) |
63 evaluators.append(evaluator) |
62 evaluators.append(evaluator) |
64 self.evaluators = sorted(evaluators, key=lambda x: x.priority) |
63 self.evaluators = sorted(evaluators, key=lambda x: x.priority) |
65 |
64 |
66 def process(self, req, path): |
65 def process(self, req, path): |
67 """given an url (essentialy caracterized by a path on the server, |
66 """Given an url (essentialy caracterized by a path on the |
68 but additional information may be found in the request object), return |
67 server, but additional information may be found in the request |
69 a publishing method identifier (eg controller) and an optional result |
68 object), return a publishing method identifier |
70 set |
69 (e.g. controller) and an optional result set. |
71 |
70 |
72 :type req: `cubicweb.web.Request` |
71 :type req: `cubicweb.web.request.CubicWebRequestBase` |
73 :param req: the request object |
72 :param req: the request object |
74 |
73 |
75 :type path: str |
74 :type path: str |
76 :param path: the path of the resource to publish |
75 :param path: the path of the resource to publish |
77 |
76 |
78 :rtype: tuple(str, `cubicweb.utils.ResultSet` or None) |
77 :rtype: tuple(str, `cubicweb.rset.ResultSet` or None) |
79 :return: the publishing method identifier and an optional result set |
78 :return: the publishing method identifier and an optional result set |
80 |
79 |
81 :raise NotFound: if no handler is able to decode the given path |
80 :raise NotFound: if no handler is able to decode the given path |
82 """ |
81 """ |
83 parts = [part for part in path.split('/') |
82 parts = [part for part in path.split('/') |