[Grok-dev] Containers with different object types and traversal

Leonardo Rochael Almeida leorochael at gmail.com
Fri Mar 27 13:23:30 EDT 2009


Hi Steve,

It seems to me that the simplest way to accomplish what you want is to
put two (subclasses of) Containers inside your Performance instance,
called "musicians" and "songs". Inside each of these sub-containers
you would then place, respectively, your musician and song instances.

You could use either the __init__ of your Performance class or a
subscriber to ObjectAddedEvent that matched against your Performance
instance to create your sub-folders.

This would give you the URLs you wish.

Cheers, Leo

On Fri, Mar 27, 2009 at 13:05, Steve Schmechel <steveschmechel at yahoo.com> wrote:
>
> I know I once saw a complete list of rules for default traversal, but I can not seem to find it again.  Does anyone know where a list like that can be found?
>
> I thought that traversal included looking for fields within an object that could be traversed.  For example, an object with a field that is a container of other objects could be traversed as:
> /AppContainer/ObjectName/ContainerField/ContainedObjectName
>
> Which would be handy if you had an object that had two fields that were containers of different sets of objects:
> /AppContainer/ObjectName/OtherContainerField/OtherContainedObjectName
>
> However, as I sure most of you know, this does not work by default.  It seems that to contain anything that is traversable (without employing a custom traverser), you need to use grok.Container.
>
> I'll admit that it is taking me a while to get used to using containers as content objects with their own fields.  Maybe, I have spent too much time with relational databases and other object models where containers (data tables, collections, dictionaries, etc.) and the stuff they contain (data rows, simple objects, etc.) are worked with very differently.
>
> So, I finally saw some documentation on traversal of nested containers (on the Repoze.bfg site).  Of course, this makes sense to me when I think about a Plone site with a folder that contains another folder.  But, in Plone, the folder was just a folder and you couldn't add much direct content except by specifying another object to be the default view that "covers up" the folder's URL.
>
> I was happy to find that grok.Container objects work fine with schemas and autoforms.  It seems I just need to dump all of my various content types into one parent container.  As long as the keys do not collide, this should work.
>
> I do have some questions about this arrangement.
>
> How to I keep the key string from conflicting?  I do not want to create contrived names that end up in the URL.  What kind of schemes to people use to keep the different types of objects from colliding?  (I'm not specifically talking about the "NameChooser" concept, although it may play into the solution.)
>
> Example:
>
> I have a container object that represents a musical performance by a band.  It has a list of songs that will be performed and a set of musicians that will be playing that day.  I want to be able to have something like:
>
> /SpecificPerformance/musicians/BrianWilson as the url of a model object that defines a musician object and the instrument being played at that performance.
>
> Now, if the band in playing a song called "BrianWilson" (BNL fans will get this reference ;-), I would have:
> /SpecificPerformance/songs/BrianWilson as the url of a model object that defines a song and it's arrangement and key for this performance.
>
> Now, if these are going to be in the same container I need a way to tell them apart.  Do I do something with the keys like:
> /Performance/musicians-BrianWilson
> /Performance/songs-BrianWilson
> This seems kind of ugly.
>
> Do I have to use something like z3c.Traverser to get the URL back to the original form, but leave the keys as above?
>
> Can I subclass grok.Container and an add another dictionary and expect traversal to still work?
>
> There seems to be something close to this in the tests for zope.traversing at:
> http://svn.zope.org/zope.traversing/trunk/src/zope/traversing/tests/test_traverser.py?rev=96010&view=auto
>
> Where:
>
>    def testTraversingDictSeesDictAPI(self):
>        adict = {
>            'foo': 'bar',
>            'anotherdict': {'bar': 'foo'},
>            'items': '123',
>            }
>        tr = Traverser(adict)
>        self.assertEqual(tr.traverse('items'), adict.items)
>        self.assertEqual(tr.traverse('anotherdict/bar'), 'foo')
>        self.assertEqual(tr.traverse('anotherdict/items'),
>                         adict['anotherdict'].items)
>
> It looks like, if you had another dictionary in the object, you could traverse to that also.  This would basically accomplish what I wanted to do in the first place, but by modifying a component rather than simply arranging them in a particular way.
>
> Has anyone done something like this?
>
> Any feedback is welcome.
>
> Thanks,
> Steve
>
>
>
> _______________________________________________
> Grok-dev mailing list
> Grok-dev at zope.org
> http://mail.zope.org/mailman/listinfo/grok-dev
>


More information about the Grok-dev mailing list