A Beginners Guide to the World of Zope
Just a loose collection of commented links to things I found useful for getting around with Python, Zope, CMF, and Plone. (Raphael Ritz, March 2003).
Major Resources
Python: http://www.python.org
Zope: http://www.zope.org (the community) and http://www.zope.com (Zope Corporation)
Zopes Content Management Framework (CMF) http://cmf.zope.org
Plone, the currently most advanced (from what I know) front end to the CMF at http://plone.org
Documentation
Python:
- the definitive reference: http://www.python.org/doc/
- to get started (for otherwise experienced programmers): http://diveintopython.org/
- to get started from scratch: How to think like a computer scientist http://www.ibiblio.org/obp/thinkCSpy/
Zope:
- The Zope Book (2.6 edition): http://www.zope.org/Documentation/Books/ZopeBook/2_6Edition
- Zope Developers Guide: http://www.zope.org/Documentation/Books/ZDG/current/index_html
- Zope Cookbook at http://www.zopelabs.com
- Dieter Maurer's upcoming(?) Building Dynamic Web Sites with Zope: http://www.dieter.handshake.de/pyprojects/zope/
CMF
Unfortunately there is no comprehensive book on the CMF available up to now but there are bits and pieces on various topics. And there is some documentation that ships with the distribution and that's available through the Help section of the management interface.
Plone
- The book of Plone: http://plone.org/documentation/book/
Various
- Why use a Content Management System from University College London: http://www.engineering.ucl.ac.uk/plone/manual/ (addresses users and site managers of a (potential) Plone site in a universtity setting
More specific tools for finding Documentation
or how to effectively search for something related to your problem:
- Full-text searchable mailing list archives:
- at active state: http://aspn.activestate.com/ASPN/Mail
- at New Information Paradigms Ltd.: http://zope.nipltd.com/public/lists.html
- documentation generating tools:
- DocFinder (http://www.handshake.de/~dieter/pyprojects/zope/DocFinder.html)
in conjunction with DocFinderEverywhere: http://www.zope.org/Members/shh/DocFinderEverywhere
DocFinder can be of great help when discovering object APIs and debugging security problems. It furthermore treats docstrings as structured text which is a very powerful feature as it allows to write nicely-formatted documentation right into the source, while having it instantly available TTW.
- HappyDoc: http://happydoc.sourceforge.net/
HappyDoc is a tool for extracting documentation from Python source code. It differs from other such applications by the fact that it uses the parse tree for a module to derive the information used in its output, rather that importing the module directly. This allows the user to generate documentation for modules which need special context to be imported.
- Zpydoc: http://www.last-bastion.net/Zpydoc
Zpydoc is an initiative to apply the standard documentation formalisms utilised within Python to Zope - itself a Python application. Its basically a wrapper to make
pydoc(but also much more) available from within Zope directly.
- DocFinder (http://www.handshake.de/~dieter/pyprojects/zope/DocFinder.html)
in conjunction with DocFinderEverywhere: http://www.zope.org/Members/shh/DocFinderEverywhere
Random Gotchas
(as they come to my mind) Here I collect without any specific ordering topics that help to understand a few of the more involved topics of the Zope way of doing things.
- Zope's database ZODB and storage means
Out-of-the-box Zope comes with a transactional, hierarchical object database, the ZODB http://www.zope.org//Members/runyaga/ZopeFAQs/WhatWhyHowZODB Its default represenation on disk is as one (potentially large) file in Python's pickle format. This is refered to as file system storage; the filename is
Data.fsand its located in Zope'svardirectory'. There are alternatives like directory storage http://dirstorage.sourceforge.net/index.html or adaptable storage http://hathaway.freezope.org/Software/AdaptableStorage under development (now called APE for adaptable persistence). Moreover Zope can talk to almost any (reasonable) RDBMS. - Object/Name/Method Look up (or how Zope finds out about things)
Apparently this is one of the most confusing issues beginners stumble accross as it involves a variety of advanced concepts.
- Multiple Inheritance
As Zope is written in Python, Zope objects are instances of Python classes. Python supports multiple inheritance and Zope makes (excessive?) use of this. This means, when you define a class as in
class myclass(baseclass1,baseclass2, ...)you can derive it from as many other classes as you like where each in turn can be derived from arbitrary other classes etc. This can make it hard to figure out which methods are available to a particular class because you need to scan all base classes (and their base classes etc) to find out. This is what DocFinder does for you. Note that the order in which the base classes are specified is important because look up is from left to right. So in case of a conflict (to different base classes provide the same method) Python just takes the first it finds.Example Say you want to define your own folderish content type for the CMF. You do this by deriving from
PortalContentandPortalFolder. But depending on whether you useclass myFolderishType(PortalContent,PortalFolder)orclass myFolderishType(PortalFolder,PortalContent)you will end up having different behaviour, e.g., with respect to theportal_catalogbecausePortalFolderoverwritesindexObject()andreindexObject()to do nothing. So in the first case above your content type will be covered by the catalog whereas in the second it wont be. - Acquisition
In the ZODB an object can only be created in a container which in turn has to "live" in another container (except for
root) and so on. This imposes a hierarchical structure among the objects and it is this structure that Acquisition makes use of. If a method is called on an object that the object itself does not provide (neither by itself nor through inheritance) then Zope starts looking for the method in the object's container and if it still can't find it there it looks into the container's container and so on. To make sensible use of this you need to carefully consider where to place which objects since this makes a difference depending on the container's properties. This concept for look up is called acquisition by containment.To make it a bit more confusing there is a further twist in the concept of acquisition called acquisition by context: When you invoke a method on an object you can do so by specifing the objects path from the root and then appending the method like in
/topfolder/somefolderA/subfolder/object/mymethod(note the URL format of method invocation here, i.e., you can do this directly via a web browser). Now suppose none of the folders here nor the object provide the methodmymethodbut that there issomefolderBin parallel tosomefolderAin the topfolder which providesmymethod. You can now extend your call to/topfolder/somefolderB/somefolderA/subfolder/object/mymethodand the method will be found. Through extending the path you have changed the context in which the method is called and acquisition makes use of this for the look up. - Skinning
This is a concept to extend name/method look up that the CMF adds to Zope. I like to think of this as having multiple different search pathes to choose from. Suppose you have a number of folders
f1, f2, ..., fnholding different versions of the same set of methods (but there is no need to have each method in each folder). Now you define a skin by saying: for skin A first look inf1, then look inf2, then inf3whereas skin B might be defined as: first look inf2, then inf3, then inf1and so on. That way you can provide, e.g., different designs to choose from (like through having different style sheets in the different folders).But the concept is more powerful than to just provide different designs (or skins; that's where the name is coming from). In principle you can use it to provide multiple object behaviour, meaning that you can make objects behave differently in response to particular method calls if the method is implemented to do different things in the different skin folders.
Another nice feature provided through this concept is that you can easily customize methods without interfering with the original source code (this is a huge maintenance plus). The CMF does this by making the default skin folders available as
file system directory viewsto the ZODB and therefore to Zopes through the web (TTW) management interface (ZMI). If you now navigate to one of those folders and you select a method you can just clickcustomizeand Zope will place a copy of the method in yourcustomskin folder which you can edit now as you like. Since thecustomskin folder is typically placed before the default skin folders in the look up pathes of the skins your method will be found first whenever called. Note that you did not change the original method in any way. It is still there and as soon as you delete (or rename) your customized copy it will be in place again (very useful if you screw things up).
- Multiple Inheritance
- The ZCatalog
This is what you need in order to search the database (effectively). For plain Zope you need to build one yourself whereas CMF/Plone come with a pre-configured
portal_catalog. There are some issues that aren't obvious at the beginning, like indexes, brains, and meta data so I sketch them here.- Index: You can query the catalog only on an index and there are several types of indexes
supporting different functionality, e.g., on
field indexesyou can sort (and do range searches) whereas ontext indexesyou can't sort but enable globbing (using wildcards). - brains: The catalog does not hold (copies of) the objects indexed themself but rather
a reference object to them called
brainorcatalog brainin Zope terminology. Brains provide methods likegetObject()orgetURL()to get at the respective object or its URL. Furthermore brains can be equiped with - catalog meta data to have some attribute values or results of method calls to the object availabel right away (without having to access the object). It's up to you how many meta data you want (or can afford) to put on your brains. You basically trade disc space for performance.
For a real intro see http://www.zope.org/Documentation/Books/ZopeBook/2_6Edition/SearchingZCatalog.stx
- Index: You can query the catalog only on an index and there are several types of indexes
supporting different functionality, e.g., on
- What the CMF adds to Zope
Whereas Zope by itself is a very general framework for enabling a lot of applications (mainly around web publishing but not necessarily tied to it; e.g., the ZODB can also be used stand alone in any Python application) the CMF adds some functionality and tools designed for building web-based content management systems. Among the tools there are some for registration, membership- and member-data handling, the aforementioned catalog and skins tool, a workflow engine, a types tool and so on.
- Some caveats with respect to CMF versus Zope
To play nice with the extensions that the CMF brings on top of Zope some Zope ways of doing things should be avoided. It is generally not recommended to use the ZMI to manipulate portal content because this typically circumvents the "CMF-wrapper methods" that ensure proper notification of the various CMF tools.
Example: To create in instance of a portal content object you should use
invokeFactorywhich wraps the constructor through the types tool which in turn asures catalog notification and workflow initialization. Creating the instance through the ZMI would just call the constructor and the catalog or workflow engine would not know.Another consequence is that plain Zope objects can't typically be used in a CMF setting because standard Zope objects do not provide the appropriate hooks (attributes and methods) needed by the CMF machinery. (More on this in "Extending Zope" below)
Extending Zope/CMF/Plone
In addition to the developer's guide I found this useful to get started:
- for Zope
- for CMF/Plone
- Basic CMF product: http://www.zope.org/Members/digitalis/basic_cmf_product/
- Localizing CMF: http://cmf.zope.org/Members/rthaden/LocCMFProduct/niLocCMFProduct
- Minimal Plone product: http://www.zope.org/Members/ingeniweb/PloneMinimalProduct
- For Plone in particular: CMFTypes (http://sourceforge.net/projects/collective) soon to become Archetypes (http://sourceforge.net/projects/archetypes/)
More generally http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/collective/ is always a good place to check for the state of the art in Plone add-ons.
Interoperability
or connecting to the rest of the (IT) world. The CMF provides a syndication tool to support outbound syndication (making your stuff available to others in an XML dialect called RSS/RDF) but for inbound syndication you need to add some modules.
Web services still aren't in the focus of the Zope community but there are some projects on that
- Syndication/RDF handling
- News feeds: http://www.zope.org/Members/EIONET/RDFSummary and more advanced: http://www.zope.org/Members/hellmann/CMFNewsFeed/README and for Plone in particular CMFSin from http://sourceforge.net/projects/collective
- Event feeds: http://www.zope.org/Members/EIONET/RDFCalendar
- extended XML-RPC support: http://www.zope.org/Members/EIONET/XMLRPC
- Example for including a web service via SOAP in Zope: http://software.biostat.washington.edu/statsoft/snake/RSessionDA
- A page about REST: http://www.prescod.net/rest/
