Zope Products
Last month we took an initial look at the open-source Zope application server. In particular, we saw how you can use Zope's DTML (dynamic template markup language) tags to create simple dynamic sites, as well as how you can manage a web site using nothing more than a web browser.
But anyone who has worked with DTML knows that it ceases to be wonderful when you want to create something relatively complex. DTML is best when it is used sparingly or when its functionality is obvious; writing pages of DTML that contain a half-dozen nested conditional (<dtml-if>) tags quickly becomes unreadable and difficult to maintain, not to mention very nonmodular.
Another problem is that DTML exists inside of individual documents, rather than in a central location. If we want to reuse functionality in multiple places, then we must copy our DTML methods and documents. This means that when we want to add or change some functionality, we must go through each of the copies and modify them as well.
The solution to this problem is the Zope product. Each Zope product is actually an object class (or a set of classes) that can be instantiated any number of times in our web site.
This month, we look at Zope products, which form the core of Zope's flexibility. After installing and working with some existing products, we will write our own simple product in Python.
A Zope product is a package of code, graphics and DTML that provides a piece of reusable functionality. For example, if we were interested in creating a simple page that displays the current time, we could create a DTML document:
<p>It is now <dtml-var name="ZopeTime" fmt="fCommon">.</p>
But what if we want to expand our page, displaying a weather forecast retrieved via HTTP from another server? DTML is not the answer here; even if we could use it to create our custom functionality, the result would be difficult to manage, as well as ugly to write. Because Zope products are written in Python, they can use any Python module they like, displaying their output in HTML or any other compatible format.
Because each product is treated as a single entity, we can install and remove them as a single unit even if it defines and uses a number of classes. However, this doesn't mean that each product stands on its own; on the contrary, it is possible for one product to use functionality provided by another product.
In addition to products and DTML documents, Zope provides two other means for creating dynamic content: Python scripts (implemented by a product, no less) allow us to write and use small Python programs within Zope. We also can create, edit and use new products using a system known as ZClasses. ZClasses allow you to create new products (and their associated classes) using nothing more than your web browser and DTML.
While these four options provide a great deal of flexibility, deciding which one to use can sometimes be difficult for beginning Perl programmers. Beehive's The Book of Zope, which I review in this issue of Linux Journal, suggests using ZClasses at the beginning of a project, migrating the code to a full-fledged product after everyone has agreed upon a design. The more complex your functionality is, the more likely it is that you will want to use or write a product rather than rely on DTML and Python scripts.
You can run almost every aspect of Zope products via the Zope management screen, which you can reach via the /manage URL of your Zope server. Click on the control panel link in the left-hand frame to bring up the Zope control panel and on the Product Management link in the main frame to bring up the product management screen.
You should see a list of Zope products, along with a button marked “Add product” at the top of the screen. Products that you can modify through the Web (including ZClasses, which we briefly mentioned above) are identified with an open box, whereas standard Zope products have a closed-box icon. A closed box simply means that you cannot modify the product itself via the Web. However, most products will let you customize them by setting one or more properties via a web-based interface. But the product itself remains unchanged, unless you modify the source code.
Each product is actually a directory under your Zope installation directory in lib/python/Products. The Sessions product is under lib/python/Products/Sessions, while the Transience product is in lib/python/Products/Transience. (I installed Zope under /usr/local/zope/ on my system, so Sessions is actually in /usr/local/zope/lib/python/Products/Sessions/.) A product directory contains Python code, text files and directories, including:
__init__.py: this is what Zope scans and executes when it loads your module. Among other things, the initialize method in __init__.py invokes context.registerClass, which (as its name implies) tells Zope that your product exists, what text to display in the Add menu on the /manage screen (with the meta_type parameter) and how to create a new instance of your product when the Add button has been pressed (with the constructors parameter).
README.txt: as its name implies, this is the README file for a particular product. Clicking on a product name from within the control panel will display a README tab, among others. This tab allows you to look at README.txt without having to look at the filesystem. If the product directory contains no file named README.txt, then no README tab will appear at the top of the screen.
version.txt: this file contains the name and current version number of your product, separated by minus signs (-). Version 1.2.3 of the product Foo thus will have a version.txt with the following contents: Foo-1-2-3. This version information is displayed in the control panel.
Help files: a product may contain a help directory, which contains the text displayed by Zope when you click on the help link. Help files are often written using structured text, a minimalist formatting system similar in spirit to Perl's POD documentation system. Structured text is easy to write with a simple text editor and equally easy to read with a standard Linux tool like less.
Zope only looks at the current list of products when it starts up. This means that if you install a new product, you will need to restart your Zope server. This is done most easily from within the control panel.
Now that we have seen what a typical product may contain, we will install a product by downloading it from the Zope web site, unpack it within lib/python/Products and restart Zope. If all goes well, our newly installed product should then appear in our control panel screen. Moreover, we will be able to create new instances of this product anywhere we want in our web hierarchy.
For example, let's create a Slashdot clone using the Squishdot product for Zope. Our first task is to retrieve a copy of Squishdot from www.zope.org/Products. Squishdot is listed under the Feedback category, among others, and probably will be one of the first products listed. Click on the links that lead to a downloadable version of Squishdot; the latest version as of this writing is 1.3.0. Notice how even a product of moderate complexity is relatively small; the Squishdot version that I downloaded was a little more than 256KB.
To install Squishdot, we must unpack it into lib/python/Products. Assuming that we place newly downloaded files in /downloads, this means that we can unpack Squishdot in the following way:
# Set this to your Zope home export ZOPE=/usr/local/zope # Switch into the products directory cd $ZOPE/lib/python/Products # Unpack Squishdot into the current directory tar -zxvf /downloads/Squishdot-1-3-0.tar.gz
Older Zope products expect to be unpacked from the Zope root directory, rather than from within lib/python/Products. Unfortunately, there does not seem to be any obvious way to know how a product was packaged without looking at it:
tar -ztvf /downloads/ProductName.tar.gz
If each filename begins with the lib/python/Products pathname, then you will want to switch into $ZOPE, rather than $ZOPE/lib/python/Products, before unpacking the product.
Unpacking the archive is all we need to do in order to install Squishdot. However, Zope only looks for products when it starts up; we must restart the server before we can create instances of Squishdot on our system. The best way to do that is to click on the Restart button from within the control panel. Don't panic if your browser complains that the server is no longer running after you click on Restart, or if you see an obscure-looking Python exception backtrace after clicking on the Restart button. Rather, wait several seconds before clicking again on the control panel link in the left-hand frame, and it should work.
You can check to see if your product has been added by returning to the Product Management page within the control panel. If the newly installed product (Squishdot, in this case) does not appear on the list, double-check that it was unpacked correctly and that the permissions allow the Zope user access to the product's files.
At this point, we should be able to create a new Squishdot site by moving to the root (/) directory of the Zope server, selecting Squishdot site from the selection list and clicking on Add. This invokes the methods named in the constructors parameter to context.registerClass, invoked by the initialize function in Squishdot's __init__.py.
And indeed, we could move ahead and create our Squishdot site at this point. But Squishdot uses the Zope MailHost object (which represents an SMTP server) to send e-mail notifications. If you have not yet created and defined a MailHost, the Squishdot configuration screen will remind you to do so.
When Squishdot looks for a MailHost, it begins its search in the current directory. If it does not find a MailHost object, the search continues up the directory tree, stopping when Squishdot reaches / or when it finds a MailHost object. While this might appear to be a simple issue, it demonstrates the concept of acquisition, which is central to Zope. Moreover, it means that different Squishdot sites can send e-mail via different SMTP servers, simply by creating more than one MailHost object. Indeed, we can define a global default MailHost in /, overriding it as necessary by placing additional MailHost objects in subdirectories. The concept of acquisition permeates Zope and means that we can define or redefine nearly anything—MailHosts, users, headers and stylesheets—at a local level.
In this particular case, we will create an instance of MailHost in the / directory by choosing MailHost from the new product list and clicking on Add. Because a MailHost object represents an SMTP server, the configuration of this object is pretty straightforward, requiring that we enter the name of our Zope server's SMTP server. Most Linux machines run their own mail servers, so “localhost” is probably a reasonable value.
The mandatory ID field is used to identify this MailHost uniquely within the current directory, which is why Zope uses IDs to identify objects in URLs uniquely. Just as a filename is a unique identifier within a directory, a Zope object ID is a unique identifier within a folder or other object. The optional Title field is meant for humans, rather than for the underlying Zope server; if it is defined, an object's title is displayed from within the Zope server interface.
After you have created your MailHost object, you will be returned to the main Zope management screen for /. You should see your new MailHost object (represented with a small envelope icon), along with any title that you defined, in the list of objects.
We are now ready to create our Squishdot site. Add a new Squishdot site object using the selection list and Add button in the upper right-hand corner, choose an ID (i.e., URL pathname), optional title and mailhost, and then select some other basic parameters for your Squishdot site. For example, I chose an ID of atf and otherwise left the configuration options with their default values.
To enter my Squishdot site, I now tell my web browser to display http://localhost:8080/atf/. Zope receives this request for /atf and sees that we are referring to a Squishdot object. Zope then asks this object to display itself. Sure enough, we see an introductory screen that looks something like Slashdot but is powered by Zope.
We can create as many Squishdot sites as we might like, keeping in mind that every new site must have its own unique ID. In this way, we can set up one moderated site, one unmoderated site and another internal site for our organization's own uses—each with its own URL, potentially protected with its own set of users and groups.
To modify the Squishdot site, simply append /manage to the name of the object you want to modify, as in http://localhost:8080/atf/manage. This invokes Zope's management system on our Squishdot site. Using tabs at the top of the screen, you can modify nearly any parameter having to do with Squishdot, from moderation rules to the color of the text in which the site name is displayed.
This month we discussed Zope products and saw how to download, install and configure products on our system. While products are inherently more complex than simple DTML pages, their centralized code and additional flexibility make them more suitable for serious tasks than DTML.
Next month we will look at how we can write our own Zope products using a combination of Python and DTML.












Comments
Re: At the Forge: Zope Products
Very nice article!
Greate list of the ready for use Zope products can be found on content management software info
Modular DTML & the future of Zope Products
The author says: "DTML exists inside of individual documents, rather than in a central location. If we want to reuse functionality in multiple places, then we must copy our DTML methods and documents". Of course DTML methods can be isolated, modularized, and re-used. All that is required is to create a seperate DTML object, and to include a DTML reference at the point where it should "appear" in the document. How hard is that?
However, the observation that DTML ceases to satisfy as the task complexity increases is spot on. That's where Python Methods come in. Regardless, Zope Page Templates are the current "better way" to do DTMLish things. For the lone Zopemeister DTML may be fine, but not for Zope coders toiling in environments where Web Designers are cranking out "look and feel" using their favorite "Web Processors". Popular WYSIWYG page weavers just can't swallow DTML tags without pitching a fit.
As for Zope Products, there are lots of them out there, and like DTML, they will linger for a long while even after the whole Zope Product way has succumbed to Zope Components. The trend is already clear, as seen in the Zope Content Management Framework (CMF), the component core of which forms the foundation of Zope v.3. Open Source projects are so dynamic due to the constant flurry of improvement and discovery. Still, the rate of change can be a bit draining.
The gotcha that Zope Product fans eventually tumble to is a total lack of integratability at the object level. Any large project must be thoroughly designed at the outset, or suffer from endless re-writes as new and unanticipated features are added. Zope Product coders must wake up at night in terror of the boss asking them to merge two pre-existing packages to consolidate functionality. Zope Components promise to remedy this problem, even more completely than ZPatterns does with it's abstraction of databases and other resources to enable object sharing between applications.
Re: At the Forge: Zope Products
for a really good example of Zope at its finest check out plone.
Re: At the Forge: Zope Products
I think this statement is not quite true. Every experienced DTML programmer should know well about how to create code logic and reuse it throughout the site, rather than copying DTML codes into individual documents.
Most of the problem is that you'll easily meet DTML gochas if there's no concrete sense of acquisition.
Re: At the Forge: Zope Products
This is WRONG !
Acquisition allows you to have ONLY one method and use it anywhere. That's acquisition and that's good (tm)
Didier.
Please do not say things unless you know about !
Re: At the Forge: Zope Products
DTML is going to fade away soon because of new technology
available in Zope 2.5
ZPT (Zope Page Templates) are the way to go now,
NOT a combination of python and DTML. DTML IS DEAD. LONG LIVE ZPT!.
With ZPTs you can have 100% separation of code, design and content. You can write just (extended, but correct) HTML pages using WYSIWYG tools and some python scripts.
Read ZPT ZWiki pages or more info
The most powerfull product (extension) for ZOPE is CMF (Content Management Framework) used together with DCWorkflows. CMF services will be part of Zope3 core (this summer).
plese write something about making Products (or Products for CMF), but NO DTML PLEASE!@!@!
David Pravec -- IRC nick alekibango
/join #zope at IRC server irc.openprojects.net
Re: At the Forge: Zope Products
DTML is going to fade away soon because of new technology
available in Zope 2.5
ZPT (Zope Page Templates) are the way to go now,
NOT a combination of python and DTML. DTML IS DEAD. LONG LIVE ZPT!.
With ZPTs you can have 100% separation of code, design and content. You can write just (extended, but correct) HTML pages usig WYSIWYG tools and some python scripts.
Read ZPT ZWiki pages or more info
The most powerfull product (extension) for ZOPE is CMF (Content Management Framework) used together with DCWorkflows. CMF services will be part of Zope3 core (this summer).
plese write something about making Products (or Products for CMF), but NO DTML PLEASE!@!@!
David Pravec -- alekibango
/join #zope (at irc server irc.openprojects.net)
Re: At the Forge: Zope Products
ZPT may well acheive the laudable aim of separating layout from logic ut it odes so at the expense of comprehension. ZPT has to be one of the most ridiculous technologies I have ever come across. EVERYTHING about it is counter-intuitive. Code (and by that I include HTML) is meant to be read (not separated), and ZPT is a fairly pointless nightmare (DTML is as bad as, say, ASP or PHP but at least you can work out what it does.)
One of the benefits of ZPT is that designers can work on the same page as programmers. Oh come on, I've yet to meet a designer that couldn't knacker up the "hidden" code with a page with their eyes shut.
And as for WYSIWYG tools, well I've yet to meet a hardcore designer who will admit to using them.
Zope is more than a single technology, and DTML is one strand (which I both loathe and love) that, even if is a bit odd is still easier to understand and use than sodding ZPT.
tom
Re: At the Forge: Zope Products
DTML is a better solution than ZPT for hand-coded templates.
DTML is not going anywhere, and is better suited for these examples since (correct me if I'm wrong here) this site is written for humans, and not for WYSIWYG applications
Re: At the Forge: Zope Products
Nice article... I can't find the other article refered to on the zope server though?
Does anybody now where to find it.
Re: At the Forge: Zope Products
The first part of this article is:
http://linuxjournal.com/article.php?sid=5619
if this is what You mean ...
Re: At the Forge: Zope Products
Right now, it looks like it is only available in the print version of last month's LJ.
Re: At the Forge: Zope Products
I really like Zope a lot but the Products system is one part of it I would really like to see improved.
1) Everything can be done over the web interface, except installing products. There is one product that enables this function BUT it only works if the products are packaged in a consistant way, which they aren't. Yes, such a system would be a security hazard. I wouldn't attempt it without strong admin passwords and SSL.
2) The products vary wildly in quality, usefulness, completeness and how you install them. Squishdot is a shining example of a fully-functional product. What would be helpful would be,
a) Standard root directory to zip/tgz the product from,
b) Products passed through a QA system before being "official", like Postnuke do,
c) Minimum standards for documentation i.e. it might be useful to know what some of these products actually do before downloading them,
d) A "tested against" chart to see what version of Zope the product would work with,
e) Screenshots for all of them!
Re: At the Forge: Zope Products
In response to your points:
Having said that, Zope is so easy to install that I have zope running on a variety of boxes (including windoze) and mostly "Q&A" products myself before deploying them on my production server.
Martin Wehipeihana
Re: At the Forge: Zope Products
Well written; I found it very useful. Good work
Re: At the Forge: Zope Products
Yepp, well done mate.
Perhaps you should have mentioned something about the
mxm Easy Product (http://www.zope.org/Members/maxm/HowTo/easyProduct)
Another article another time perhaps? ;-)
Post new comment