Chris McDonough wrote:
>> On the other hand, I do understand some motivation for this for
>> creating eclectic URL layouts. But I wonder if there's a better way?
>> In particular, make sure that writing routing code isn't hard, so that
>> custom code for different site layouts is easy. There are at least
>> two modest methods in WebOb for this -- req.path_info_peek() and
>> req.path_info_pop(), which both get the next segment of the URL.
>> Along with req.urlvars (and req.urlargs) there's a way to save the
>> captured data without having to instantly inspect the model (unless
>> you want to inspect the model). And domain names can be just as valid
>> a thing to parse, and don't really fit any traversal pattern.
> That blew my stack, sorry.
Well, maybe an example where graph traversal seems easier is something
like a filesystem (or ZODB filesystemish system) with verbs at the end.
E.g., /path/to/file.txt/view, /path/to/file.txt/edit, etc. You could
do something like:
path, verb = req.path_info.rsplit('/', 1)[-1]
if not verb:
verb = 'index'
obj = File(path)
return getattr(obj, verb)(req)
Though I think even better would be something like:
fs = Filesystem()
segment = req.path_info_peek()
if segment is None:
elif segment == '': # trailing /
fs = fs[segment]
And maybe that's more complicated than simple traversal, I don't know.
One thing I was thinking about as a general idea was to look for
.wsgi_application on objects, and use that. Then traversable objects
might look like:
def __init__(self, path):
self.path = path
wsgi_application = TraverseGetitem('index')
def __getitem__(self, segment):
return self.__class__(os.path.join(self.path, segment))
def __init__(self, index_meth=None):
self.index_meth = index_meth
def __get__(self, obj, type=None):
if obj is None:
def app(environ, start_response):
req = Request(environ)
next = req.path_info_peek()
next = obj[next]
next = None
next = None
if next is None:
next = self.index_meth
if isinstance(next, basestring):
next = getattr(obj, next)
if hasattr(next, '__get__'):
next = next.__get__(obj)
if hasattr(next, 'wsgi_application'):
next = next.wsgi_application
return next(environ, start_response)
>> So I'd be interested in use cases people have where Routes alone isn't
>> enough. I'm sure these exist (I could come up with a few), but I'm
>> also pretty sure there's other solutions than object publishing.
>>> - Its equivalent of the publisher doesn't attempt to traverse into
>>> *code* stored in the object graph. All code is on the filesystem.
>>> The only thing in the object graph is "model" data.
>> How do you deal with distinguishing between model instantiation data,
>> and traversal of the models themselves? E.g., /archive/2008/06/ --
>> /archive probably points to an Archive class or an instance
>> (singleton?) of ArchiveManager or something. /2008 and /06 probably
>> translate to datetime(2008, 6) or something along those lines, which
>> provide the arguments to instantiate an Archive object, and then you
>> call some default method like index or __call__.
> It's simpler than that. We are always traversing model instances. We
> just call __geitem__ the whole way through the model graph until we
> either exhaust the path or find an item that doesnt have a __getitem__
> or whose __getitem__ raises a KeyError. The "next" name becomes the
> view name. Any leftover path elements become a "subpath". It really is
> just block and tackle graph traversal of data, there's nothing tricky
> going on.
The views are code, yes? How are view names mapped to code? Presumably
you can have a URL ".../view" where the actual function called depends
on the type of object you traversed to. The examples don't make this clear.
Ian Bicking : [EMAIL PROTECTED] : http://blog.ianbicking.org
Repoze-dev mailing list