Re: [Repoze-dev] traversal vs url dispatch for rest'ish applications

2009-06-30 Thread Chris McDonough
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

2009-06-30 Thread Iain Duncan
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

2009-06-30 Thread Tres Seaver
-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

2009-06-30 Thread Tres Seaver
-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

2009-06-29 Thread Chris McDonough
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

2009-06-29 Thread Iain Duncan

 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