Helping ordinary people create extraordinary websites!
HOME TUTORIALS SCRIPTS WEB HOSTING BLOG FORUM
Get Our Newsletter
Email:

Extending Python and Zope in C

By Michael Roberts
2004-12-04


Going all out With a Product

The power-tool method of extending Zope is the Product. At the installation level, a Product is just a directory in the "lib/python/Products" directory under the Zope directory. You can see lots of examples in your own Zope installation, but essentially, a minimal Product consists of just two files in its directory: an arbitrarily named code file, and a file called __init__.py that Zope calls to initialize the Product at startup. (Note that Zope only reads Product files at startup, meaning that for testing you must be able to stop and restart the Zope process.) This article only hints at the vast amount of stuff you can do with Zope Products.

The thing to understand is that a Product packages up one or more classes that can be used from ZClasses, scripts, or directly from URLs over the Web. (In the last case, of course, instances of the Product are treated as folders; then the last part of the URL names the method to be called, and it returns arbitrary HTML.) You don't have to treat a Product as an "addable" object, but that's its primary purpose. For a good real-life example, take a look at the ZCatalog implementation, part of the standard Zope distribution. There you will see a fairly simple installation script in __init__.py, and in ZCatalog.py you can see the ZCatalog class, which presents a number of methods for publication. Note that Zope uses an odd convention to determine which methods are accessible via the Web -- if a method has a doc string, it is Web accessible; otherwise, it's considered private.

At any rate, let's look at a very simple Product that uses our C module defined up above. First, a very simple __init__.py; note that the only thing this does is to tell Zope what the name is of the class we're installing. More elaborate initialization scripts can do a lot more, declaring global variables to be maintained by the server, setting up access privileges, and so on. For a lot more detail, see the Zope Developer's Guide in the online documentation and study the stock Products in your Zope installation. As you might have guessed, our example Product is called "Foo". Thus you would create a Foo subdirectory in your lib/python/Products directory.

import Foo

def initialize(context):
context.registerClass(
Foo.Foo,
permission='Add Foo',
constructors=Foo.manage_addFoo
)
Now notice that this initialization script not only imports the class in order to make it accessible to other parts of Zope, it also registers it for "addability". The context.registerClass call does that by naming the class we imported, then specifying the name of a method that can be used to add an instance (this method must display a management page, and it will automatically be integrated with the Zope management interface). Cool.

So let's scratch out a simple little Product. It will expose our foo.bar function to scripts and ZClasses, and it will also have a little interface as an "addable" object, and that's about all.

import foo

class Foo(SimpleItem.Item):
"A Foo Product"
meta_type = 'foo'
def bar(self, string):
return foo.bar(string)
def __init__(self, id):
"Initialize an instance"
self.id = id
def index_html(self):
"Basic view of object"
return '
My id is %s and its length is %d.
' % (self.id, foo.bar(self.id))
def manage_addFoo(self, RESPONSE):
"Management handler to add an instance to a folder."
self._setObject('Foo_id', Foo('Foo_id'))
RESPONSE.redirect('index_html')
This is just barely a Product. It's not quite the absolute tiniest possible Product, but it's close. It does illustrate a few key insights about Products, though. First, note the "index_html" method; it is called to present an object instance, and it does so by building HTML. It's effectively a page. The manage_addFoo method is our interface to Zope object management; it was referenced above in our __init__.py. The "__init__" method initializes the object; all it really must do is record the instance's unique identifier.

This micro-Product doesn't interact with Zope security. It doesn't do much management. It has no interactive features. So there's a lot you could add to it (even besides useful functionality, which it also doesn't have.) I hope it's a good start for you.

Tutorial Pages:
» The Best of Both Worlds
» Extending Python for Fun and Profit
» Writing the Code
» Building the Extension
» Taking it to Zope
» Creating an External Method
» Zope scripts: Cliff Notes version
» Going all out With a Product
» Where to go From Here
» Resources


First published by IBM DeveloperWorks


 | Bookmark
Related Tutorials:
» Python and Java - A Side by Side Comparison
» Learn Python in 10 Minutes
» Python 201 - (Slightly) Advanced Python Topics
» Python 101 - Introduction to Python
» Google Sitemaps
» Python 101