[Zope3-dev] Absolute URLs and Named vs. Unnamed Adapters

Brad Bollenbach bradb at bbnet.ca
Fri Apr 15 15:26:41 EDT 2005


Hi,

I'm writing a bug tracker in Zope 3 called Malone:

    https://launchpad.ubuntu.com/malone/products/malone

It's part of a larger suite of tools to help people develop, translate
and distribute open source software. It's the bug tracker that is
being used by some Ubuntu Linux maintainers, and will eventually be
adopted by the official Ubuntu maintainer team in the not-so-distant
future.

It's there for people who want to use it, and for people who want to
make it extremely easy for bug fixes in their development trees to
easily propogate into distribution packages, and vice versa.

So, enough shameless self-promotion. :)

I'm experiencing a problem with getting the absolute url of a thing in
ZPT vs. Python code, and I'm fairly sure that it has to do with the
internals of how Zope 3 looks up the adapter for IThing that provides
IAbsoluteURL when I issue a zapi.absoluteURL call.

Here's an example of how I want to access it in ZPT (context is an
IBug):

    <div class="portletBody"
         tal:define="bug_url context/@@absolute_url">
        <div class="portletContent odd">
    ...

Here's an example of how I want to access it in Python code (e.g. in
an event handler that sends out mail notification when a bug changed):

    ...
    if changes:
        changes["bug"] = new_bug
        changes["bugurl"] = zapi.absoluteURL(new_bug, request)
        changes["user"] = user

        return BugDelta(**changes)
    ...

The latter was working fine, using the following ZCML to register the
view providing IAbsoluteURL:

    <view
        for="canonical.launchpad.interfaces.IBug"
        factory="canonical.launchpad.browser.bug.BugAbsoluteURL"
        type="zope.publisher.interfaces.http.IHTTPRequest"
        permission="zope.Public"
        provides="zope.app.traversing.browser.interfaces.IAbsoluteURL">
    </view>

But the former (context/@@absolute_url) was breaking with an error like:

    TypeError: There isn't enough context to get URL information. This
    is probably due to a bug in setting up location information.

etc.

So I named the view:

    <view
        for="canonical.launchpad.interfaces.IBug"
        name="absolute_url"
        factory="canonical.launchpad.browser.bug.BugAbsoluteURL"
        type="zope.publisher.interfaces.http.IHTTPRequest"
        permission="zope.Public"
        provides="zope.app.traversing.browser.interfaces.IAbsoluteURL">
    </view>

Which then causes the zapi.absoluteURL code to raise the TypeError and
the ZPT to work fine!

I'm not intimately familiar with the internals of this code, but by
the looks of it, behind the scenes of zapi.absoluteURL, a lookup is
being done for an unnamed multi-adapter, and thus, naming my view
"absolute_url" breaks that lookup. This means I need to include *both*
ZCML snippets above for this functionality to work, i.e. I need to
register both a named *and* an unnamed adapter for /@@absolute_url and
zapi.absoluteURL to both work.

Would it be reasonable to improve the adapter lookup so that only one
ZCML registration is required in this situation? Perhaps the adapter
lookup should first try to find an adapter called absolute_url, and if
no such adapter exists /then/ try to find an unnamed adapter providing
IAbsoluteURL? Any other suggestions for approaches to make this Just
Work whilst only requiring one registration in ZCML?

Cheers,

--
Brad Bollenbach



More information about the Zope3-dev mailing list