summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt5
-rw-r--r--docs/narr/resources.rst74
-rw-r--r--pyramid/traversal.py42
3 files changed, 95 insertions, 26 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index e5b46678c..b4f367607 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -28,6 +28,11 @@ Documentation
- Added "Determining if a Resource is In The Lineage of Another Resource" to
Resources narrative chapter.
+- Added "Finding the Root Resource" to Resources narrative chapter.
+
+- Added "Finding a Resource With a Class or Interface in Lineage" to
+ Resources narrative chapter.
+
1.0a7 (2010-12-20)
==================
diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst
index 1e54f9eef..fe1f760bb 100644
--- a/docs/narr/resources.rst
+++ b/docs/narr/resources.rst
@@ -462,6 +462,35 @@ parent (or one of its parent's parents, etc.) is an ancestor.
See :func:`pyramid.location.inside` for more information.
+Finding the Root Resource
+-------------------------
+
+Use the :func:`pyramid.traversal.find_root` API to find the :term:`root`
+resource. The root resource is the root resource of the :term:`resource
+tree`. The API accepts a single argument: ``resource``. This is a resource
+that is :term:`location` aware. It can be any resource in the tree for which
+you want to find the root.
+
+For example, if the resource tree is:
+
+.. code-block:: python
+ :linenos:
+
+ class Thing(object): pass
+
+ a = Thing()
+ b = Thing()
+ b.__parent__ = a
+
+Calling ``find_root(b)`` will return ``a``.
+
+The root resource is also available as ``request.root`` within :term:`view
+callable` code.
+
+The presence or absence of a :term:`virtual root` has no impact on the
+behavior of :func:`~pyramid.traversal.find_root`. The root object returned
+is always the *physical* root object.
+
.. index::
single: resource interfaces
@@ -472,14 +501,15 @@ Resources Which Implement Interfaces
Resources can optionally be made to implement an :term:`interface`. An
interface is used to tag a resource object with a "type" that can later be
-referred to within :term:`view configuration`.
+referred to within :term:`view configuration` and by
+:func:`pyramid.traversal.find_interface`.
Specifying an interface instead of a class as the ``context`` or
``containment`` predicate arguments within :term:`view configuration`
-statements effectively makes it possible to use a single view callable for
-more than one class of resource object. If your application is simple enough
-that you see no reason to want to do this, you can skip reading this section
-of the chapter.
+statements makes it possible to use a single view callable for more than one
+class of resource object. If your application is simple enough that you see
+no reason to want to do this, you can skip reading this section of the
+chapter.
For example, here's some code which describes a blog entry which also
declares that the blog entry implements an :term:`interface`.
@@ -576,6 +606,40 @@ directly provided by an instance instead of overwriting them like
For more information about how resource interfaces can be used by view
configuration, see :ref:`using_resource_interfaces`.
+Finding a Resource With a Class or Interface in Lineage
+-------------------------------------------------------
+
+Use the :func:`pyramid.traversal.find_interface` API to locate a parent that
+is of a particular Python class, or which implements some :term:`interface`.
+
+For example, if your resource tree is composed as follows:
+
+.. code-block:: python
+ :linenos:
+
+ class Thing1(object): pass
+ class Thing2(object): pass
+
+ a = Thing1()
+ b = Thing2()
+ b.__parent__ = a
+
+Calling ``find_interface(a, Thing1)`` will return the ``a`` resource because
+``a`` is of class ``Thing1`` (the resource passed as the first argument is
+considered first, and is returned if the class or interface spec matches).
+
+Calling ``find_interface(b, Thing1)`` will return the ``a`` resource because
+``a`` is of class ``Thing1`` and ``a`` is the first resource in ``b``'s
+lineage of this class.
+
+Calling ``find_interface(b, Thing2)`` will return the ``b`` resource.
+
+The second argument to find_interface may also be a :term:`interface` instead
+of a class. If it is an interface, each resource in the lineage is checked
+to see if the resource implements the specificed interface (instead of seeing
+if the resource is of a class). See also
+:ref:`resources_which_implement_interfaces`.
+
.. index::
single: resource API functions
single: url generation (traversal)
diff --git a/pyramid/traversal.py b/pyramid/traversal.py
index 73878022c..f3377b0d0 100644
--- a/pyramid/traversal.py
+++ b/pyramid/traversal.py
@@ -44,7 +44,7 @@ def find_resource(resource, path):
Rules for passing a *string* as the ``path`` argument: if the
first character in the path string is the with the ``/``
character, the path will considered absolute and the resource tree
- traversal will start at the root object. If the first character
+ traversal will start at the root resource. If the first character
of the path string is *not* the ``/`` character, the path is
considered relative and resource tree traversal will begin at the resource
object supplied to the function as the ``resource`` argument. If an
@@ -86,13 +86,13 @@ find_model = find_resource # b/w compat
def find_interface(resource, class_or_interface):
"""
- Return the first object found in the parent chain of ``resource``
- which, a) if ``class_or_interface`` is a Python class object, is
- an instance of the class or any subclass of that class or b) if
- ``class_or_interface`` is a :term:`interface`, provides the
- specified interface. Return ``None`` if no object providing
- ``interface_or_class`` can be found in the parent chain. The
- ``resource`` passed in *must* be :term:`location`-aware.
+ Return the first resource found in the :term:`lineage` of ``resource``
+ which, a) if ``class_or_interface`` is a Python class object, is an
+ instance of the class or any subclass of that class or b) if
+ ``class_or_interface`` is a :term:`interface`, provides the specified
+ interface. Return ``None`` if no resource providing ``interface_or_class``
+ can be found in the lineage. The ``resource`` passed in *must* be
+ :term:`location`-aware.
"""
if IInterface.providedBy(class_or_interface):
test = class_or_interface.providedBy
@@ -179,7 +179,7 @@ def traverse(resource, path):
in the ``path``. The ``view_name`` will be a Unicode object or
the empty string. The ``view_name`` will be the empty string if
there is no element which follows the ``context`` path. An
- example: if the path passed is ``/foo/bar``, and a context
+ example: if the path passed is ``/foo/bar``, and a resource
object is found at ``/foo`` (but not at ``/foo/bar``), the 'view
name' will be ``u'bar'``. If the ``resource`` was found via
urldispatch, the view_name will be the name the route found was
@@ -190,7 +190,7 @@ def traverse(resource, path):
the ``view_name`` (if any). Each of these items is a Unicode
object. If no path segments follow the ``view_name``, the
subpath will be the empty sequence. An example: if the path
- passed is ``/foo/bar/baz/buz``, and a context object is found at
+ passed is ``/foo/bar/baz/buz``, and a resource object is found at
``/foo`` (but not ``/foo/bar``), the 'view name' will be
``u'bar'`` and the :term:`subpath` will be ``[u'baz', u'buz']``.
For a ``resource`` found via url dispatch, the subpath will be a
@@ -210,7 +210,7 @@ def traverse(resource, path):
See :ref:`vhosting_chapter` for a definition of the virtual root
object. If no virtual hosting is in effect, and the ``path``
passed in was absolute, the ``virtual_root`` will be the
- *physical* root object (the object at which :term:`traversal`
+ *physical* root resource object (the object at which :term:`traversal`
begins). If the ``resource`` passed in was found via :term:`URL
dispatch` or if the ``path`` passed in was relative, the
``virtual_root`` will always equal the ``root`` object (the
@@ -218,9 +218,9 @@ def traverse(resource, path):
- ``virtual_root_path`` -- If :term:`traversal` was used to find
the ``resource``, this will be the sequence of path elements
- traversed to find the ``virtual_root`` object. Each of these
+ traversed to find the ``virtual_root`` resource. Each of these
items is a Unicode object. If no path segments were traversed
- to find the ``virtual_root`` object (e.g. if virtual hosting is
+ to find the ``virtual_root`` resource (e.g. if virtual hosting is
not in effect), the ``traversed`` value will be the empty list.
If url dispatch was used to find the ``resource``, this will be
``None``.
@@ -230,7 +230,7 @@ def traverse(resource, path):
Rules for passing a *string* as the ``path`` argument: if the
first character in the path string is the with the ``/``
character, the path will considered absolute and the resource tree
- traversal will start at the root object. If the first character
+ traversal will start at the root resource. If the first character
of the path string is *not* the ``/`` character, the path is
considered relative and resource tree traversal will begin at the resource
object supplied to the function as the ``resource`` argument. If an
@@ -367,7 +367,7 @@ def virtual_root(resource, request):
the resource object representing the :term:`virtual root` of the
current :term:`request`. Using a virtual root in a
:term:`traversal` -based :app:`Pyramid` application permits
- rooting, for example, the object at the traversal path ``/cms`` at
+ rooting, for example, the resource at the traversal path ``/cms`` at
``http://example.com/`` instead of rooting it at
``http://example.com/cms/``.
@@ -375,8 +375,8 @@ def virtual_root(resource, request):
:term:`traversal`, and if the ``HTTP_X_VHM_ROOT`` key is in the
WSGI environment, the value of this key will be treated as a
'virtual root path': the :func:`pyramid.traversal.find_resource`
- API will be used to find the virtual root object using this path;
- if the object is found, it will be returned. If the
+ API will be used to find the virtual root resource using this path;
+ if the resource is found, it will be returned. If the
``HTTP_X_VHM_ROOT`` key is is not present in the WSGI environment,
the physical :term:`root` of the resource tree will be returned instead.
@@ -526,8 +526,8 @@ def quote_path_segment(segment):
class ResourceTreeTraverser(object):
""" A resource tree traverser that should be used (for speed) when
- every object in the tree supplies a ``__name__`` and
- ``__parent__`` attribute (ie. every object in the tree is
+ every resource in the tree supplies a ``__name__`` and
+ ``__parent__`` attribute (ie. every resource in the tree is
:term:`location` aware) ."""
implements(ITraverser)
@@ -633,8 +633,8 @@ class ResourceTreeTraverser(object):
ModelGraphTraverser = ResourceTreeTraverser # b/w compat
class TraversalContextURL(object):
- """ The IContextURL adapter used to generate URLs for a context
- object obtained via resource tree traversal"""
+ """ The IContextURL adapter used to generate URLs for a resource in a
+ resource tree"""
implements(IContextURL)
vroot_varname = VH_ROOT_KEY