On 03/02/2011 07:34 PM, Joe Dallago wrote:
So I am relatively new to the Pyramid scene, so correct me if I am
wrong, but this is the conclusion I have come to on this topic.  B/c I
too struggled for a few days over this.

Resources:  First of all, resources were originally called "models,"
but the name was purposely changed to avoid confusion with SQLAlchemy
"models" or with the normal idea of what a MVC "model" is.  A
"resource" is simply one element in the "resource tree."  The entire
purpose of the resource tree is to define the structure of your site.
A resource isn't necessarily connected to a persistence system, such
as an RDBMS, but it definitely can be.  It is also important to note
that the resource tree is only used when traversal is used as the
routing system.  Traversal is simply the process by which the router
moves down the resource tree according to the url, and assigns the
context and view.

Context:  In traversal, the context is the last resource that is
loaded as the router traverses the resource tree, either due to the
fact that there are no elements left in the url or that the router has
reached the bottom of the tree.

View:  The view is element of the url that directly follows the
context(i.e. /pages/add, if 'pages' is loaded as the context, then
'add' becomes the view).  It is essentially the function that does all
of the business logic and sends important information to the template.
  In traversal the context found through the traversal is passed into
this view function, whereas in Url Dispatch, the root_factory defined
when the view is added to the registry creates an object that is
passed into the view as the context(this could be the root of your
application or even another resource that you might want to use in the
view, it just has to be a class).

As Chris said, great description, thank you!

I don't know about the zope.interfaces question.

Disclaimer: Many (most?) Pyramid apps, even ones that use traversal, never need to use interfaces. You can build all sorts of useful stuff w/o interfaces. If you don't want to know about interfaces, please happily pretend they don't exist, and don't read any further.

For those of you still interested, however, interfaces can be useful when you want more "pluggability". In most of Pyramid's traversal examples, views are registered against resource classes, so the edit view for a BlogPost class would be different than the edit view for a User class, which would be different again from the edit view for a Photo class. But what if all of your different resource types support tags, and you have a single ``tags`` view that would work for all of them? You could register the same view 3 times, for 3 different context types. Or you could register your view against an ITaggable interface:

  from myproject.interfaces import ITaggable
  @view_config(name='tags', context=ITaggable)
  def tags_view(request):
      context = request.context
      ... {do tags stuff here } ..


Now you'd declare that all of the taggable resource types support the ITaggable interface, by putting an ``implements(ITaggable)`` in the class definition, like so:

  from zope.interface import implements
  from myproject.interfaces import ITaggable
  class BlogPost(object):
      implements(ITaggable)
      def __init__(self):
          ... {do blogpost stuff here} ...

If you're building a framework of some sort, then someone else who develops a taggable custom resource type can get the tags view for free by adding the ``implements(ITaggable)`` line to their class definition.

Note that interfaces used as such are really just flags on the class; an interface doesn't actually have to define an API. In fact, an interface can be completely empty:

  from zope.interface import Interface
  class ITaggable(Interface):
      pass

An interface CAN define an API, however. If it does so, then any class that declares support for the interface should implement the specified API. This will not be enforced... you can lie about it and declare a class to support an interface when it actually doesn't. Not typically a good idea, though. ;)

-r

--
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en.

Reply via email to