After the basic code and interfaces, comes the trick of wiring the content objects into Zope 3. This is done via ZCML, an extensible configuration language that defines and describes components for use in Zope 3. ZCML may appear to be verbose, and I have not always been its biggest fan, but I have learned that it is almost always better to be explicit than implicit. Zope 2 often made many implicit assumptions. For the most part, this wasn't a problem. But when it was a problem, it was usually something hard to find and debug. When found, it was usually something in the system that was doing something clever and assumptive that the developer didn't expect it to be clever and assumptive about.
So now that our interfaces and content classes are in, it's time to wire them in. Using ZCML, we can define behavior and interfaces for objects outside of code. For example, declaring IAttributeAnnotatable support allows other Zope 3 components to add annotations. Annotations include things like Dublin Core support, which lets Zope 3 track title, description, modified time, etc, without the developer needing to code in support themselves like they did (or inherited) in Zope 2. Much of the security declarations that filled in Zope 2 python based product code is moved to ZCML. Other elements of ZCML might be recognized as similar to the Python code in the Product
<configure xmlns="http://namespaces.zope.org/zope"> <interface interface=".interfaces.ITodoList" type="zope.app.content.interfaces.IContentType" /> <content class="todo.TodoList"> <implements interface="zope.app.annotation.interfaces.IAttributeAnnotatable" /> <implements interface="zope.app.container.interfaces.IContentContainer" /> <factory id="todo.TodoList" description="Todo List"/> <require permission="zope.ManageContent" interface=".interfaces.ITodoList" /> </content> <interface interface=".interfaces.ITodo" type="zope.app.content.interfaces.IContentType" /> <content class="todo.Todo"> <implements interface="zope.app.annotation.interfaces.IAttributeAnnotatable" /> <implements interface="zope.app.container.interfaces.IContentContainer" /> <factory id="todo.Todo" description="Todo"/> <require permission="zope.ManageContent" interface=".interfaces.ITodo" /> <require permission="zope.ManageContent" set_schema=".interfaces.ITodo" /> </content> <include file="browser.zcml"/> </configure>
The last line,
include file="browser.zcml", I'll get to shortly. That is where the web interface is wired in. So far in developing this little project, I've only learned and done the basic add and edit forms, which are really easy in Zope 3. This is where the interface schema items will come into play. Similar, I assume, to how Ruby On Rails has Scaffolding.
But what we've done so far is setup the Model objects and wired them into the basic Zope 3 application. Next - standard views and controllers.