there are quite a few solutions out there in the Zope world that
allow the management of relations or references between objects.
So I have been working with the reference engine provided by
Archetypes (as part of Plone) for nearly two years now; and I
also had a look at some proposals on zope.org and
implementations that are available in the Zope 3 packages from
SchoolTool and CPSSkins.
I have to confess that I was not really happy with any of these
proposals or solutions - a feeling that we may discuss in more
detail, the main point being just that I wanted to have
something simple that is nevertheless flexible enough to
accommodate to various needs.
So I came up with the following stuff (mainly combining concepts
by Jean-Marc Orliaguet and implementation ideas from Archetypes
A relation is an object providing the IRelation interface. This
has got two attributes ('first', 'second' - dyadic relation) or
three ('first', 'second', 'third' - triadic relation). (You may
ignore triadic relations if you don't think you need them.)
If I now create corresponding classes (DyadicRelation,
TriadicRelation) I can assign the objects taking part in a
relation directly to these attributes of the relation. (Note
that the objects taking part in a relation are not touched at
all.) In fact I create a class for each kind of relation (each
relationship or predicate or whatever you like to call it)
I want to use.
So the question arises what to do with the relation objects? The
point here is not so much where to store them but how to make
sure that we can find them. So we need a registry for relations
- interface IRelationsRegistry.
This has three methods:
The keyword arguments to the query() method may be:
- relationship=... - a relation class (we can also work with
named predicates - see below)
- first=... - an object
- second=... - an object
- third=... - an object
One can combine those arguments at will to search for all
relations of the relation class specified (if given) with the
given values for the attributes. The list may be extended if you
use relation classes with additional attributes you want to
(For details have a look at the README.txt and other files on
or check it out via
svn co svn://svn.cy55.de/Zope3/src/cybertools/trunk/relation)
You see that this looks very much like a catalog search - so why
not implement the relations registry as a subclass of
OK, so the RelationsRegistry class is derived from Catalog, and
of course it is a local utility. The indexes are just FieldIndex
objects, using an adapter to provide unique ids for the objects
involved via the IntIds utility; the same is done for providing
ids for the relation objects themselves. The relationship is
mapped to the full module path + class name of the relation
An interesting consequence of this is that the relation objects
are not explicitly stored somewhere, the only reference to them
is via the IntIds utility. Thus you are free to store them in
some container or even make them first class content objects if
you want - but you needn't.
The whole stuff is flexible enough to be extended as needed, e.g.
with special registry classes used via named utilities,
additional attributes on relations (easily indexable in the
registry); it could be wrapped in a richer and more
application-oriented API, etc.
It is also possible to use named predicates (with URIs or strings
like '_ is child of _') instead of different relation classes to
represent relationships (this is shown by an example at the end
of the README.txt).
So what do you think? - any feedback and suggestions welcome...
I'd also gladly write a proposal (if I get write access to the
wiki ;-)) and of course change the license from GPL to ZPL if
this would be considered useful.
Zope3-dev mailing list