Writing Zope Products
Last month, we continued our discussion of the Zope web development environment by installing and examining Zope products. As we saw, each product is actually a Python object module that can be instantiated one or more times on a Zope server. Hundreds of products are available for Zope, ranging from a small and lightweight fortune-teller to the large and impressive content management framework (CMF).
Many Zope administrators are content to install and use the products that they can download from the Web. And indeed, there are enough products to satisfy most basic sites; whatever you cannot do with an existing product is often simple enough to create in DTML, Zope's Dynamic Template Markup Language (described in the February 2002 issue of LJ).
But as easy and straightforward as it may be to do many tasks in DTML, it is neither as complete nor as flexible as Python. And while the addition of PythonScripts (and PerlScripts!) in Zope has certainly reduced the need to write products for many medium-sized tasks, most Zope hackers eventually find themselves writing a product of some sort.
This month, we look at how to build a simple Zope product that we can then integrate into our site. As you will see, it is quite easy to create a Zope product that integrates well into the rest of this environment.
At its core, a Zope product is a Python module. The product (as we saw last month) is installed into the lib/python/Products directory under the main Zope directory. Zope looks for products when it is started (or restarted), which means that you must start or restart Zope after installing a new product.
We can instantiate an installed product as many times as we like, placing each instance somewhere in the web hierarchy. Each instance has a unique “id” attribute that both uniquely identifies it within a folder and allows us to invoke methods on the object.
If this already sounds confusing, remember that the URL /foo/bar normally means that a web server should retrieve the file “bar” within the directory “foo”. But in Zope, the URL foo/bar means that the system should invoke the method “bar” on the object “foo”. In other words, foo/bar gets turned into foo.bar. And when we say “the object foo”, we really mean to say, “the object whose ID is foo”. Setting the ID is essential if we are going to invoke methods on our object successfully.
We also will need to define a meta_type for our product. The meta_type name is the text string that will appear in the Add pull-down list of Zope products in the upper-right corner of the /manage screen. In general, you can name the meta_type the same as your class or perhaps something a bit easier to understand. Remember that items in the Add menu are displayed in ASCII order, which means that capital “Z” comes before lowercase “a”.
To create our own product, we need to do the following:
Define a class in its own module and install it in lib/python/Products.
Define an __init__ method in which we assign the “id” instance variable a value.
Define one or more methods whose return value is a text string containing HTML.
Define a meta_type class variable, which sets the meta_type for all instances of our product.
This turns out to be surprisingly simple to do, as you can see in Listing 1, which defines helloworld.py, a simple Zope product that you can install and almost instantiate in your site. (We'll soon see how to get around these limitations.)
There are several important items to notice in our helloworld class. For starters, the class and its methods contain documentation strings. It's always a good idea to write docstrings, and Python's inclusion of such a feature is a rare and refreshing reminder that programmers can and should include documentation along with the source code. Zope enforces this restriction by mandating that classes and methods must include docstrings if you want them to be used in the system.
Our class also defines two methods, __init__ and index_html. The __init__ method is invoked automatically by Zope when it creates an instance of our object and typically is used to initialize instance variables and define other behaviors that will be needed later on. In this particular case, __init__ defines a single instance variable (self.id) that allows our object to keep track of its identity. As you might expect, __init__ is not meant to be invoked from the outside world, but rather from within Zope itself.
The index_html method, by contrast, is designed to be invoked via a URL. If we place an instance of “helloworld” in the root (/) directory of our Zope server, we can invoke the index_html method on it with a URL of /helloworld/index_html. But index_html is special; like the index.html file on many Apache servers, it is invoked by default if no other method is named explicitly.
Finally, notice that index_html returns HTML to its caller. It does not return a status code or anything other than the HTML.
|Using Salt Stack and Vagrant for Drupal Development||May 20, 2013|
|Making Linux and Android Get Along (It's Not as Hard as It Sounds)||May 16, 2013|
|Drupal Is a Framework: Why Everyone Needs to Understand This||May 15, 2013|
|Home, My Backup Data Center||May 13, 2013|
|Non-Linux FOSS: Seashore||May 10, 2013|
|Trying to Tame the Tablet||May 08, 2013|
- Using Salt Stack and Vagrant for Drupal Development
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- New Products
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Validate an E-Mail Address with PHP, the Right Way
- A Topic for Discussion - Open Source Feature-Richness?
- New Products
- New Products
- The Pari Package On Linux
- Home, My Backup Data Center
- This is the easiest tutorial
3 hours 11 min ago
- Ahh, the Koolaid.
8 hours 49 min ago
- git-annex assistant
14 hours 49 min ago
- direct cable connection
15 hours 11 min ago
- Agreed on AirDroid. With my
15 hours 22 min ago
- I just learned this
15 hours 26 min ago
15 hours 56 min ago
- not living upto the mobile revolution
18 hours 47 min ago
- Deceptive Advertising and
19 hours 23 min ago
- Let\'s declare that you have
19 hours 24 min ago
Enter to Win an Adafruit Prototyping Pi Plate Kit for Raspberry Pi
It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Prototyping Pi Plate Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- Next winner announced on 5-21-13!
Free Webinar: Linux Backup and Recovery
Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.
In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.