Better access to APIs in paths (was Re: [Zope3-dev] needing views clues - template/title troubles)

Jim Fulton jim@zope.com
Sun, 23 Feb 2003 09:23:21 -0500


Troy,

Your note brought home to me that there are good things about Zope 2
that we don't want to lose in Zope 3.  I'd like, over the next month or so,
to put some more emphasis on the general topic of what's good
in Zope 2 and making sure we retain the good things of Zope 2 in Zope 3.

Troy Farrell wrote:
> This is not about developing Zope 3.  This is about a new user's 
> experience.  If you don't have time for this, press delete now.
> 
> Greetings zopethreestas.
> Having heard much of Z3 and planning developement using it in the 
> future, I decided to give it a whirl.  I cvs co'd Zope3 last night and 
> got it running.  I tried a few things that seemed familiar from Z2. 
> Files and images are neat and worked fine.  Next up was pagetemplates.
> 
> I remember in an email from Steve A that 'here' had become 'context', so 
> that wasn't a problem.  I decided to start with one line :)  The problem 
> came in the form of a NotFoundError when I tried this and only this in a 
> pagetemplate:
> 
> <span tal:content="context/title"/>
> 
> That didn't work, so I tried
> 
> <span tal:content="template/title"/>
> 
> I know that both the container (a folder) and this template have a 
> title. 

They have titles, but the titles are no longer content data, but rather
meta data.  The title is now part of the Dublin Core meta data for an object.
To get at the dublin core meta data, you need to use an adapter, which isn't
currently possible in ZPT.

Note that in Zope 3, we don't require content objects to implement *any*
special  APIs. This is in stark contrast to Zope 2, which required content
objects to implement many many APIs. We've tried to make Zope 3 much easier
for developers and to make it much easier to reuse non-Zope software in Zope 3.

This raises an interesting issue. While we've made life easier for content
developers, we've made life harder for scripters.  Zope 2 objects have
hundreds of handy API methods that support scripting. Perhaps we need
something *like* that for Zope 3. In fact, I'm sure we do.

Hm ...

> From browsing source and seeing lots of @@somethingHere (not to
> mention all the ++etc++Services that keep showing up :), I've deduced 
> that I need to be able to use a @@somethingHere, but I have no clue what 
> a @@somethingHere is.  I was wondering if a kind soul could point me in 
> the right direction. 

Well, there isn't really an easy way to get there from here.

> If I'm asking in the wrong place or at the wrong
> time, let me know.

Not at all.

"title" is not part of the content schema, which is OK. To get it,
we need to get an adapter, which is easy enough from Python:

   getAdapter(ob, IZopeDublinCore).title

We could make this even simpler with a suggestion of Itamar's:

   IZopeDublinCore(ob).title

But this is still not as conventient as it might be. It's especially
inconventient for a ZPT path expression, because you first need
to get hold if IZopeDublinCore.

Zope 2 would make this really easy:

   ob.title

but to do that, Zope 2 requires that everyone include title
in the content schema, which is bad. Worse, if someone forgets
to define a title, then Zope 2 will acquire the title from some
other object, which could be very suprising.

The thing Zope 2 does well here is to make common APIs convenient.
The thing Zope 3 does well here is to be explicit.

Maybe we can get the best of both. Suppose we define a new type of
components called an "API" that is meant to be conveneint and informal.
APIs would be registered for interfaces, like adapters, but would be
looked up by name. There would be an "api" function, somewhat in the
spirit of Python's super. Suppose we define an API attribute, title.
We might register a title attribute hendler based on the zope dublin
core something like this::

    <api
      name="title"
      for="zope.app.interfaces.annotation.IAnnotatable"
      factory="zope.app.dublincore.annotatableadapter.TitleAPI"
      >
        title meta-data attribute

        The title API attribute provides access to the (unqualified)
        Dublin-Core "Title" meta-data element.
    </api.

Then from Python, we could do:

   api(ob).title

More importantly, we invent a path syntax for ZPT that would
let us get at APIs easily. The question is, how to spell this. You want,
in a path expression, to indicate an API that is not really an attribute
of an object.  The thing you want is in a different namespace.

Zope 3 has a notion of namespace control in path expressions.
(This is similar to the namespace control facilities in XPATH, FWIW.)
In a path, you can prefix a name with a namespace prefix of the form
"++namespace++". So, for example, to access a view named "foo" you
could use:

   context/++view++foo

Accessing views is *so* common, we have a short-hand, @@:

   context/@@foo

We could provide an api namespace:

   context/++api++title

which isn't bad at all, but it might be nice to have an even shorter version,
like:

   context//title

or

   context/++/title

Thoughts?

Final note: The audience of "APIs" is scripters, so there should be an
             emphasis on informality and convenience. In the example, above,
             we defined an API attribute. APIs coould be functions or even
             complex objects. For example, we could provide a Dublin Core
             API that provided full access to dublin core data, as in:

               context/++api++dc/created

Jim

-- 
Jim Fulton           mailto:jim@zope.com       Python Powered!
CTO                  (888) 344-4332            http://www.python.org
Zope Corporation     http://www.zope.com       http://www.zope.org