Writing Zope Products
helloworld.py is a perfectly legal Zope product; we can install it in lib/python/Products, and Zope will not mind. Unfortunately, Zope also will fail to notice that helloworld.py is there at all, will not add it to the Add selection list and generally will ignore the work we did in writing our product. It's clear that we will need to beef up our skeletal product if we want it to interact with Zope. We will call this enhanced version the “smallhello” product.
For starters, we must change the structure of our product from a single standalone module file (helloworld.py) into a full-fledged Python package. A package is a directory (smallhello) within the Python search path (defined by the variable sys.path) containing one or more Python source files. In our case, the smallhello directory will contain two files: a smallhello.py file that is quite similar to helloworld.py (see Listing 2) and __init__.py (see Listing 3), which initializes and helps to register our object.
The __init__.py file first imports smallhello.smallhello, defining the module's methods and attributes. But the crucial part of __init__.py, at least as far as Zope is concerned, is the initialize method. After Zope discovers and imports smallhello, it invokes smallhello.initialize, passing it a ProductContext object (called “context”). In other words, initializing an object results in that object registering itself with the server.
The initialize routine itself is pretty straightforward, although our version does some rudimentary error trapping (using try/except) to ensure that things work correctly. Our smallhello product only passes two arguments to context.registerClass: the finalhello.finalhello object that we want to add and then a tuple of constructors that should be invoked when we want to create a new instance of our product. Remember to include a trailing comma if you pass a single item to constructors; otherwise, Zope will fail to load the product.
The constructors parameter is just one of a number of named parameters that we can pass to context.registerClass to customize the way in which our object is registered with Zope. For example, we also can pass an icon parameter that tells Zope which graphic (a filename inside of our package directory) should be placed next to instances of our package within Zope.
Turning helloworld.py into smallhello.py (see Listing 2) requires some small changes. We start by adding a method that allows Zope to create new instances of our product. By convention, such management-related methods begin with manage_, so our method is called manage_smallhello. This is the same method that was named in the constructors tuple passed to context.registerClass.
The most significant change to our smallhello class is also one of the least obvious: we have made it a subclass of OFS.SimpleItem.SimpleItem, one of the Zope product base classes provided as part of the Zope package (in the OFS.SimpleItem package). Without inheriting from SimpleItem, many things—from cutting and pasting of objects to acquisition—would fail to work as we expect, if at all. There are several possible base classes from which your products can inherit; SimpleItem, as its name implies, is designed to be the simplest and most straightforward of the bunch.
While modifying smallhello.py, I decided to add two other methods that produce content. One of them, other_html, produces output that is similar to index_html—except, of course, index_html is displayed by default when no other method is specified, while other_html only is called when explicitly named in the URL.
I also added a foo_file method that demonstrates how to return the contents of an HTML (or DTML) file from disk. It can be annoying and frustrating to put all of your HTML inside a Python module file; this way, you can keep the DTML files inside of the package directory but modify them independently of the program itself. Note that we had to import the HTMLFile method from the Globals package in order for this to work.
I modified the __init__ function in smallhello.py to take three arguments: self, id and title. (Previously, it only accepted self and id.) The __init__ function is invoked each time a new instance of smallhello.py is created, which is done through a call to manage_smallhello. Inside of manage_smallhello, our call to self._setObject sets the object ID to a generic smallhello_id, with a title of smallhello_title. Because we hard code the ID in our example, and because IDs must be unique within a folder, this means that we only can have one instance of our smallhello product in a given folder. There isn't enough space here to describe how to read and write parameters, but a quick look at the examples mentioned in the Resources section should make it obvious how to do this.
After the call to self._setObject, manage_smallhello then redirects the user's browser to the main (index_html) method. We could display some output instead, redirecting the user's browser to another method in our object, but I took the easy way out and decided to send users to /index.html on our site.
After you have installed the smallhello product, you can stop Zope and restart it again. You should see “smallhello” near the bottom of the Add menu; selecting it will send you to the index.html page on your Zope site. Because we haven't made our product as user-friendly as it could be, you will have to enter the URL manually (index_html, other_html or foo_file) in your browser. But there isn't any reason why these pages cannot contain links to each other or why other pages on the site cannot link to them.
What do you know? We've created a Zope product!
Fast/Flexible Linux OS Recovery
On Demand Now
In this live one-hour webinar, learn how to enhance your existing backup strategies for complete disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible full-system recovery solution for UNIX and Linux systems.
Join Linux Journal's Shawn Powers and David Huffman, President/CEO, Storix, Inc.
Free to Linux Journal readers.Register Now!
- Back to Backups
- Download "Linux Management with Red Hat Satellite: Measuring Business Impact and ROI"
- A New Version of Rust Hits the Streets
- Google's Abacus Project: It's All about Trust
- Secure Desktops with Qubes: Introduction
- Seeing Red and Getting Sleep
- Fancy Tricks for Changing Numeric Base
- Secure Desktops with Qubes: Installation
- Working with Command Arguments
- Linux Mint 18
Until recently, IBM’s Power Platform was looked upon as being the system that hosted IBM’s flavor of UNIX and proprietary operating system called IBM i. These servers often are found in medium-size businesses running ERP, CRM and financials for on-premise customers. By enabling the Power platform to run the Linux OS, IBM now has positioned Power to be the platform of choice for those already running Linux that are facing scalability issues, especially customers looking at analytics, big data or cloud computing.
￼Running Linux on IBM’s Power hardware offers some obvious benefits, including improved processing speed and memory bandwidth, inherent security, and simpler deployment and management. But if you look beyond the impressive architecture, you’ll also find an open ecosystem that has given rise to a strong, innovative community, as well as an inventory of system and network management applications that really help leverage the benefits offered by running Linux on Power.Get the Guide