On Mon, Oct 16, 2006 at 10:08:34AM -0500, Perry Smith wrote:

> I'm new to Zope but I've been programming for 25+ years.  I've read 
> Weitershausen's book and I'm 10 
> chapters into the Zope 3 developer's handbook.  I'm struck by its statement 
> that beginners find ZCML 
> hard.  That is true for me too.

> I keep reading and reading instead of doing which is not like me.   I
> perceive ZCML as bag of magic.  By that I mean that usually I can clearly
> define a starting point and an ending point and a hazy path between the
> two and I set off about my way.  But with Zope 3, I do not have the
> starting point and so I do not have the hazy path.  Each directive seems
> unique to the particular example in the book.  I'm unable, for some
> reason, to step back and see how ZCML is generally applied.  I'm not sure
> if it is me or the books or what.
> I'm wondering if others are or have been in my situation.  If so, can you
> offer any advise or particular things to read that will help me out.

I've been in that situation. To help all the newbies after me, I try to write
down as much as possible on zope3.mpg.de - which is unfortunately in german.

I'll try to explain ZCML in some sentences:

Every class you use (e.g. MyCalendarClass) has to be security-described in ZCML.
security declaration are working like this:
   * This is my class 'MyCalendarClass'
   * to use attribute "getNextEvent", "title" you need permission 'zope.Public'
   * to use attribute "cleanupOldEvents()" you need permission 'calendar.Writer'
   * to *write*  to attribute "title" you need permission 'calendar.Writer'

   * to make life easier, you're allowed to use '<require interface="..." .../>'
     to declare security for a bunch of attributes (the ones define in the
     interface) at once.
   * If your class is a container, you have to describe the mapping 
functionality, too.
     Mapping functionality in Python can be expressed by attributes. e.g.
     "calendar['myevent']=event" is the same as "calendar.__setitem__(event)" .
     Someone wrote all the mapping functions in interfaces - e.g.
     zope.app.container.interfaces.IWriteContainer (which contains all methods
     necessary for writing). 
   * security declarations are applied when an instance of the class is restored
     from the ZODB.

That's it for your content classes. Remember: If you write utilities or
adapter classes, you sometimes want to security-declare those classes, too.

Many objects (usually more than you think) in Zope3 are adapters or
utilities. In ZCML you'll have to define factories (e.g. callable python
objects which return an instance of the adapter/utility you want to get) for
them. The first adapter I used (I didn't even know, it's one...) was a
'<browser:page ... />'. This ZCML-statement just defines an adapter for
(context,request) to IBrowserView which is callable and returns a nice HTML
page. All the stuff in the '<browser:page>' statement configures the factory
of the browserview to i.e. include a custom template. '<browser:page />' is
nothing more than a '<adapter ... />' statement in disguise which makes you
lifer easier.

The first utility I used was a vocabulary which was a factory class (a class
implementing IVocabularyFactory). This class created a static factory that I 
to select one of four rooms in our building. At this time, I needed the
'<vocabulary .. />' statement - today this is done via '<utility ... />' which 
exactly the same.

Most of the other stuff in ZCML are disguised utility- or adapter-statements, 

Most of the problem I had, were eventually me not knowing, which interface I
needed, that I didn't know what I was actually doing (-> vocabulary: writing
an utility) or that I didn't know something very special I needed was
already provided by Zope (e.g. internationalized country names).



Zope3-users mailing list

Reply via email to