Re: [Repoze-dev] traversal vs url dispatch for rest'ish applications
On 6/30/09 1:39 AM, Iain Duncan wrote: Let's imagine a view pets: from webob import Response def pets(context, request): return Response ('OK') when a URL comes in that is for a paricular pet: from webob import Response def pets(context, request): if request.subpath: petnum = request.subpath[0] return Response('OK with petnum %s' % petnum) return Response ('OK') when a URL comes in with a particular action for a pet: from webob import Response from repoze.bfg.chameleon_zpt import render_template_to_response def pets(context, request): if len(request.subpath) == 1: petnum = request.subpath[0] return Response('OK with petnum %s' % petnum) elif request.subpath == 2: petnum, action = request.subpath return render_request_to_response('%s.html' % action, petnum = petnum) return Response ('OK') That's at least one way to handle it. Another way is to register a view for edit.html against a Pet model. Thanks Chris, the latter is what I was thinking of. So, another question, can the *context* object be a *class* instead of an instance? IE, can the class Pet be the context, such that a class level __getitem__ returns the actual instance I'm after, and edit becomes the view ( action ). This isn't a pattern that sounds familiar to me, sorry. The context is almost always an instance. It can be anything of course, but if it's a class it won't be traversed. If the class has a __getitem__, a TypeError will be raised because it will be called as an unbound method with a single argument. If I needed to do this, personally, I'd probably use traversal. I'd create a root factory (passed into make_app as the first argument) that when called with an environ returned an instance of some root object. The root object would have a __getitem__ that, given the identifier pets would return a Pets object. The Pets object would have a __getitem__ that, given an identifier, returned a Pet object representing that particular pet. Then I'd register a default view against the Pets object and both a default view and an edit view against the Pet object. That's because I've been using traversal for ten years and it's natural to me. It's not very natural for most folks. It sounds like you're more used to url dispatch. In that case, were I you, I'd forget about traversal entirely and create a few routes in the form: pets pets/:id pets/:id/edit e.g. route name=pets path=pets view=.views.pets_view / ... etc ... Each one of these would go to a separate view that did the needful. - C ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] traversal vs url dispatch for rest'ish applications
On Tue, 2009-06-30 at 06:19 -0400, Chris McDonough wrote: On 6/30/09 1:39 AM, Iain Duncan wrote: Let's imagine a view pets: from webob import Response def pets(context, request): return Response ('OK') when a URL comes in that is for a paricular pet: from webob import Response def pets(context, request): if request.subpath: petnum = request.subpath[0] return Response('OK with petnum %s' % petnum) return Response ('OK') when a URL comes in with a particular action for a pet: from webob import Response from repoze.bfg.chameleon_zpt import render_template_to_response def pets(context, request): if len(request.subpath) == 1: petnum = request.subpath[0] return Response('OK with petnum %s' % petnum) elif request.subpath == 2: petnum, action = request.subpath return render_request_to_response('%s.html' % action, petnum = petnum) return Response ('OK') That's at least one way to handle it. Another way is to register a view for edit.html against a Pet model. Thanks Chris, the latter is what I was thinking of. So, another question, can the *context* object be a *class* instead of an instance? IE, can the class Pet be the context, such that a class level __getitem__ returns the actual instance I'm after, and edit becomes the view ( action ). This isn't a pattern that sounds familiar to me, sorry. The context is almost always an instance. It can be anything of course, but if it's a class it won't be traversed. If the class has a __getitem__, a TypeError will be raised because it will be called as an unbound method with a single argument. If I needed to do this, personally, I'd probably use traversal. I'd create a root factory (passed into make_app as the first argument) that when called with an environ returned an instance of some root object. The root object would have a __getitem__ that, given the identifier pets would return a Pets object. The Pets object would have a __getitem__ that, given an identifier, returned a Pet object representing that particular pet. Then I'd register a default view against the Pets object and both a default view and an edit view against the Pet object. Thanks for the clarification, that's what I tried last night, ( called the top one PetContextFactory ). The problem I hit was that if the PCF is the end of the traversal, then the context should be a list of pets, but if it isn't, then there's no need to fetch all the pets from the db. So I think you're right, I should try url dispatch. I mostly wanted to try it with traversal first to wrap my end around Zope style traversal and see what I came up with. Thanks Iain That's because I've been using traversal for ten years and it's natural to me. It's not very natural for most folks. It sounds like you're more used to url dispatch. In that case, were I you, I'd forget about traversal entirely and create a few routes in the form: pets pets/:id pets/:id/edit e.g. route name=pets path=pets view=.views.pets_view / ... etc ... Each one of these would go to a separate view that did the needful. - C ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] traversal vs url dispatch for rest'ish applications
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Iain Duncan wrote: Thanks for the clarification, that's what I tried last night, ( called the top one PetContextFactory ). The problem I hit was that if the PCF is the end of the traversal, then the context should be a list of pets, but if it isn't, then there's no need to fetch all the pets from the db. So I think you're right, I should try url dispatch. I mostly wanted to try it with traversal first to wrap my end around Zope style traversal and see what I came up with. You might have a look at the traversal-based storm example I played with: http://svn.repoze.org/playground/tseaver/stormy/ which has both the container and the individual record-mapped objects as models. Tres. - -- === Tres Seaver +1 540-429-0999 tsea...@palladion.com Palladion Software Excellence by Designhttp://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFKSmfJ+gerLs4ltQ4RAq7cAJ0SnTweKKG6jU7FIToyVNJHAiMy3ACfcwAQ ZZUjzUQ1Xsi5Xrzj5zdVrm0= =L9TL -END PGP SIGNATURE- ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] traversal vs url dispatch for rest'ish applications
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Iain Duncan wrote: On Tue, 2009-06-30 at 15:30 -0400, Tres Seaver wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Iain Duncan wrote: Thanks for the clarification, that's what I tried last night, ( called the top one PetContextFactory ). The problem I hit was that if the PCF is the end of the traversal, then the context should be a list of pets, but if it isn't, then there's no need to fetch all the pets from the db. So I think you're right, I should try url dispatch. I mostly wanted to try it with traversal first to wrap my end around Zope style traversal and see what I came up with. You might have a look at the traversal-based storm example I played with: http://svn.repoze.org/playground/tseaver/stormy/ which has both the container and the individual record-mapped objects as models. Thanks Tres, I'll take a look. For my own edification, what made you decide to do it with traversal? My brain works that way. ;) BTW, I just updated the paster template for 'bfg_alchemy' to highlight the relationship between views on the container and views on the individual records. Tres. - -- === Tres Seaver +1 540-429-0999 tsea...@palladion.com Palladion Software Excellence by Designhttp://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFKSm6I+gerLs4ltQ4RAq3yAJ42eYXQTAudwjj/X5eoVRFoA6ILMQCg2NWW RK57Y6StAUGvg50fmfD+jNg= =9Wj4 -END PGP SIGNATURE- ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] traversal vs url dispatch for rest'ish applications
On 6/29/09 8:26 PM, Iain Duncan wrote: I'm wondering what the conventional wisdom is for doing bfg apps to handle crud operations with urls like /pet - list pets /pet/1 - view pet model, id 1 /pet/1/view /pet/1/edit - edit pet model, id 1 Is this something that can be handled well with both traversal and url dispatch? Are there any examples of it? Let's imagine a view pets: from webob import Response def pets(context, request): return Response ('OK') when a URL comes in that is for a paricular pet: from webob import Response def pets(context, request): if request.subpath: petnum = request.subpath[0] return Response('OK with petnum %s' % petnum) return Response ('OK') when a URL comes in with a particular action for a pet: from webob import Response from repoze.bfg.chameleon_zpt import render_template_to_response def pets(context, request): if len(request.subpath) == 1: petnum = request.subpath[0] return Response('OK with petnum %s' % petnum) elif request.subpath == 2: petnum, action = request.subpath return render_request_to_response('%s.html' % action, petnum = petnum) return Response ('OK') That's at least one way to handle it. Another way is to register a view for edit.html against a Pet model. ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev
Re: [Repoze-dev] traversal vs url dispatch for rest'ish applications
Let's imagine a view pets: from webob import Response def pets(context, request): return Response ('OK') when a URL comes in that is for a paricular pet: from webob import Response def pets(context, request): if request.subpath: petnum = request.subpath[0] return Response('OK with petnum %s' % petnum) return Response ('OK') when a URL comes in with a particular action for a pet: from webob import Response from repoze.bfg.chameleon_zpt import render_template_to_response def pets(context, request): if len(request.subpath) == 1: petnum = request.subpath[0] return Response('OK with petnum %s' % petnum) elif request.subpath == 2: petnum, action = request.subpath return render_request_to_response('%s.html' % action, petnum = petnum) return Response ('OK') That's at least one way to handle it. Another way is to register a view for edit.html against a Pet model. Thanks Chris, the latter is what I was thinking of. So, another question, can the *context* object be a *class* instead of an instance? IE, can the class Pet be the context, such that a class level __getitem__ returns the actual instance I'm after, and edit becomes the view ( action ). Iain ___ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev