summaryrefslogtreecommitdiff
path: root/repoze/bfg/traversal.py
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2008-08-08 23:10:20 +0000
committerChris McDonough <chrism@agendaless.com>2008-08-08 23:10:20 +0000
commitcc5e490467c105b8cce35c0bca688ed18ec93255 (patch)
treeb80b330385a9d796ea99f74b88eaaeee90d057b6 /repoze/bfg/traversal.py
parent8fc21eb80a3c0fbe2ec4984636f86acab228d6b7 (diff)
downloadpyramid-cc5e490467c105b8cce35c0bca688ed18ec93255.tar.gz
pyramid-cc5e490467c105b8cce35c0bca688ed18ec93255.tar.bz2
pyramid-cc5e490467c105b8cce35c0bca688ed18ec93255.zip
- Add ``find_context_from_path`` and ``find_root`` traversal APIs.
In the process, make ITraverser a uni-adapter (on context) rather than a multiadapter (on context and request).
Diffstat (limited to 'repoze/bfg/traversal.py')
-rw-r--r--repoze/bfg/traversal.py32
1 files changed, 30 insertions, 2 deletions
diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py
index c72c90e5e..3fe11f9f7 100644
--- a/repoze/bfg/traversal.py
+++ b/repoze/bfg/traversal.py
@@ -41,10 +41,9 @@ _marker = ()
class ModelGraphTraverser(object):
classProvides(ITraverserFactory)
implements(ITraverser)
- def __init__(self, root, request):
+ def __init__(self, root):
self.root = root
self.locatable = ILocation.providedBy(root)
- self.request = request
def __call__(self, environ):
path = environ.get('PATH_INFO', '/')
@@ -66,6 +65,35 @@ class ModelGraphTraverser(object):
return ob, name, path
+def find_root(model):
+ """ Find the root node in the graph to which ``model``
+ belongs. Note that ``model`` should be :term:`location`-aware."""
+ for location in LocationIterator(model):
+ if location.__parent__ is None:
+ model = location
+ break
+ return model
+
+def find_context_from_path(model, path):
+ """ Given a model object and a string representing a path
+ reference (a set of names delimited by forward-slashes), return an
+ context in this application's model graph at the specified path.
+ If the path starts with a slash, the path is considered absolute
+ and the graph traversal will start at the root object. If the
+ path does not start with a slash, the path is considered relative
+ and graph traversal will begin at the model object supplied to the
+ function. In either case, if the path cannot be resolved, a
+ KeyError will be thrown. Note that the model passed in should be
+ :term:`location`-aware."""
+
+ if path.startswith('/'):
+ model = find_root(model)
+
+ ob, name, path = ITraverser(model)({'PATH_INFO':path})
+ if name:
+ raise KeyError('%r has no subelement %s' % (ob, name))
+ return ob
+
def find_interface(context, interface):
""" Return an object providing ``interface`` anywhere in the
parent chain of ``context`` or ``None`` if no object providing