[Zope] Re: Two newbie questions + Zope patch

Michel Pelletier michel@digicool.com
Thu, 09 Sep 1999 01:09:13 -0400


Michel Pelletier wrote:
 
> I'm not sure what your getting at here, but if you want to resolve a
> path to a URL try:
> 
> <dtml-with "REQUEST.resolve_url((SCRIPT_NAME + '/path/to/object'))">
>   blah
> </dtml-with>
> 

Before I shot my mouth off, I should have metioned that this ability
comes with a catch.  This sort of functionality was necesary for
ZCatalog and WebDAV to resolve URLs into Zope objects, but the usage and
semantics of path=object-traversal were never standardized.  In
addition, the solution to serve the needs of the application did not,
unfortuatly, jive with ZopeFind and ZCatalog.

Brian and I had a hard time expaining the nature of the problem at the
team meeting today, so I hope this explains it to everybody.

ZopeFind is a method that will start at a container and search for
objects that meet certain criteria with the option to recursivly
traverse subfolders.  Anyone who has used the Find view in the managment
interface will be familiar with this, the interface is just an input
form to the ZopeFind method that does all the actual work.

Zope find returns a list of (relative_path, unwrapped_object) pairs. 
The relative_path, is *relative to the container from which ZopeFind was
executed in the context of*.  'unwrapped_object' is the acutal object,
not including any acquisition wrappers, therefore
'object.absolute_url()' just returns the id of the object, because there
is are no layers of acquisition wrappers to build the path from.  This
is not a problem in itself, the absolute url of the object can be built
by '(URL1 + relative_path).

A further complication however is added because of the way ZCatalog
remembers objects.  The ZCatalog.Catalog.Catalog class works on the
basis of object and their unique identifiers.  The unique identifier can
be anything at all, it is just used a document id in the class inverted
file index that ZCatalog.Catalog.Catalog uses.

The ZCatalog.ZCatalog.ZCatalog class, which is the actual Zope objects,
used a (jeez) ZCatalog.Catalog.Catalog object as its engine, what it
uses as a 'unique identifier' is the absolute *path* of the object,
which is identical to the absolute url without SCRIPT_NAME (ie
http://machine:port) in front of it; like '/absolute/path/to/object'. 
It would make no sense to catalog the whole URL, because if you changed
the name of the computer or moved the port, your catalogs would break.

'REQUEST.resolve_url(URL)' wants an absolute url beginning with http:
(like absolute_url() is supposed to return).  ZopeFind returns relative
paths with no context, and ZCatalog wants absolute paths.  The work
arounds between these three systems are simple, but the problem is that
there are three seperate APIs in Zope that work with URLs in different
ways.

Brian and I tackled this problem in ZCatalog immediatly before the final
release.  The problem was discovered when a bug was reported that
ZCatalog did not return proper URLs of objects when the Catalog was not
in the root folder.  The solution was simple, use absolute URLs
everywhere and strip SCRIPT_NAME off of URLs before cataloging them, and
with friendly community support, we found this discrepancy.

So until we work it out by coming up with a common standard and
implimenting it in the 2.1 release, use REQUEST.resolve_url(), ZopeFind
and the Catalog with caution.  When you absolutly must do it, use it
like ZCatalog does and make sure you pass it the resolve_url() the
absolute_url() of a properly wrapped object, or that you prepend URL1 to
a relative path, and strip SCRIPT_NAME from URLs before calling Catalog
methods.

-Michel

> -Michel