I've taken a quick look through the code you released (thanks!), and this prompted me to try to explain more clearly how I look at this whole issue. By the way, yours is the first Product I've read which uses the new methods for Product initialization and class registration; I didn't even know about them until I tried to understand your work :-) Adam Feuer wrote:
i don't use apache and zope together (but i should, i guess? :-)
Well, that depends on your needs. I find it very convenient to intersperse static (filesystem-based) and dynamic (Zope) content within the same URL namespace, and I use rewrite rules *very* heavily. There are (at least) three orthogonal ways in which you might want to distinguish incoming requests and decide how to serve them from Zope: o Which port/interface the request was received on o HTTP_HOST, REMOTE_USER, or other client-provided information o URL requested (almost always used, usually by ZPublisher) Any combination of these three is possible; You apparently depend heavily on the first, while I use the second. The third need not be restricted to ZPublisher's interpretation, as in my use of rewrite rules on the URL to decide between static and dynamic content. Simple 1-1 or many-1 mapping of possible values, such as you implement, handles the most popular case. Allowing arbitrary DTML or Python code to rewrite requests before they are resolved could handle any complicated scheme I can conceive of.
is one way better than the other...? i just returned the new path because it seemed like i could tread lightly on the Zope code... :-) but perhaps not...
My current (soon-to-be-released) code allows you to designate a single Zope object, which must live in the root folder, to be called for this purpose. Its return value is ignored, but it can call request methods to do its work. It can, of course, call on any number of other objects anywhere in the ZODB. Once the rewriting is done, and resolution of the URL begins, *we aren't done*. I can't tell from your posts whether you are aware of this, but I didn't see it in the code. Consider a request for '.../a/b/c', where '...' is handled by the rewriting rules (IP/port or HOST, doesn't matter), which decide that this request is for Zope path '/site1/a/b/c'. This will work fine, as long as the rendering process never refers to URLn, BASEn, or x.absolute_url(). Unfortunately, these are very useful, even critical. The management interface and many Products use these all over the place. In this scenario, if 'c' used URL2+'/d' to try to construct a reference to '.../a/d', it would instead get '.../site1/a/d'. This sort of thing result in "path bloat", where a few clicks yield '.../site1/site1/site1/site1/a/b/z'. Under Zope 1.10.3, there was a fairly simple patch which simply chopped the path additions off once they had been traversed, but this patch doesn't work in Zope 2.0, and there is a Better Way (tm). This is where SiteRoots come in. They fix up the URL data in the request as the site root is traversed. A 'site root' is just a traversable object which is meant to be the target of one or more rewrite rules. In the example scenario, 'site1' would be a site root, and would replace '.../site1' with '...' as a URL passed through it. Note that a SiteRoot can't tell whether a particular request has been rewritten with that SiteRoot in mind, or at all. Thus a straight, unchanged request for '/site1/a/b/c' will still generate URLs like '.../a/b/c'. I'm not yet sure what, if anything, need be done about this.