diff options
| author | Chris McDonough <chrism@agendaless.com> | 2008-08-08 23:10:20 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2008-08-08 23:10:20 +0000 |
| commit | cc5e490467c105b8cce35c0bca688ed18ec93255 (patch) | |
| tree | b80b330385a9d796ea99f74b88eaaeee90d057b6 /repoze/bfg/traversal.py | |
| parent | 8fc21eb80a3c0fbe2ec4984636f86acab228d6b7 (diff) | |
| download | pyramid-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.py | 32 |
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 |
