///Zope for the Perl/CGI programmer

Zope for the Perl/CGI programmer

An Initial Exploration for the Curious

Zope (the Z Object Publishing Environment) is an application server that is gaining in popularity. But what is it? What’s an application server, anyway? How does all this compare with nice familiar paradigms like CGI? More importantly, is Zope a fad, or is it here to stay?

In a nutshell, here’s what you get from Zope:

• Database integration

• Template-based page production

• User authentication,

• Selective permissions so that certain users can only update specific parts of your site

• A nice object-oriented paradigm for the distribution of custom code

• Management of persistent objects and sessions

And you get all this in an easily installed, easily maintained package. But the most significantly new thing about Zope is how it encourages you to look at your Web site differently than you do now. Let’s talk about that a little before we get down to brass tacks.

What is Zope, anyway? Zope stands for “Z Object Publishing Environment” and it is an application server implemented in Python. “Great,” you say, “but what exactly is an application server?” An application server is simply a long-running process that provides services for active content. The Web server then makes calls to the application server in order to have pages built at runtime.

We’re not in Kansas Anymore

This article, as you can see from the title, assumes you know your way around the standard CGI paradigm. Suffice it to say, you’re almost certainly used to thinking of your Web sites in terms of directories, files, and programs. The CGI-generated pages, instead of containing HTML, contain executable code that generates the HTML to be sent to the client. These pages are simply files. The point I’m making by stating the obvious is that it is natural to consider a CGI call as being a program that is run for each page hit — because that’s exactly what it is.

Under Zope, though, pages are objects in the Zope database. Zope maps URLs onto objects using a folder concept. The contents of pages are still HTML, but it’s HTML with panache: it can embed active content right into the HTML. So instead of having two fundamentally different kinds of things making up your Web site (in other words, static HTML files and active CGI programs), you simply have a bunch of Zope page objects. Instead of having programs embedding pieces of HTML in them, you have HTML embedding pieces of program, effectively. This is called templating and it’s controlled using DTML (Document Template Markup Language), which extends HTML with object-oriented specifications. It’s a lot like SSI (server-side includes) but much more flexible, as you’ll see later. Other similar technologies are ASP and JSP, and if you’ve worked with HTML::Mason in combination with mod_perl, this isn’t going to come as any great surprise, either.

An important (maybe the important) consequence of this difference is that objects under Zope may persist. Instead of a process starting up, initializing, computing, and being cleaned up for each active page hit, Zope objects can be initialized in advance and can run in-process. On a high-traffic site this can mean large performance benefits, especially when you realize that some of the most expensive resources to initialize are database connections. Zope maintains database connections for you, and so all you have to worry about for each page hit is the query itself. Again, you can get these performance benefits from mod_perl under Apache. But the point is that instead of installing Perl, mod_perl, HTML::Mason, and a raft of other modules which may or may not function together under your platform, Zope takes all this stuff and wraps it up for you.

I mentioned above that you can also toss the assumption that the filesystem is the site. Instead of putting pages in separate files and using FTP or similar tools to manage them, the Zopist puts all pages into the Zope object database, where they are arranged into folders. This sounds a little silly at first, but it allows Zope to run with a small number of file handles, cache often-used pages, and so forth. It also allows Zope to manage access to each page, so that you can define user-accessible areas, and set up users and groups very easily without the danger of giving anyone access to your operating system at all. Furthermore users can also do all their editing from any Web-enabled machine. No installation of FTP is required, and if you’ve ever walked a naive user through an FTP session on the phone, you breathe a sigh of relief at this point.

A parallel between traditional CGI and Zope occurred to me today: if you moved from C programming to Perl, you certainly remember how nice it was to work with strings under Perl as opposed to managing the memory buffers and pointers you need to do the same thing with C. The move from CGI to Zope also abstracts away a lot of the system detail that has nothing to do with the business of running Web sites. I think you’ll like it.

What is Zope, anyway? Zope stands for “Z Object Publishing Environment” and it is an application server implemented in Python. “Great,” you say, “but what exactly is an application server?” An application server is simply a long-running process that provides services for active content. The Web server then makes calls to the application server in order to have pages built at runtime.

CGI/Perl Versus Zope: Compare and Contrast

Rather than waste time with more propaganda, I’m going to cut to the chase and show you a quick little CGI program that hits a database and shows some data. Next I will show a Zope page that gives the same results. Then we can sit down and talk about how they differ. The example I’m using is straight from the Zope documentation. Just for simplicity’s sake, I’m going to assume that we’re working with a DBI installation in the Perl example. (If you haven’t heard of DBI, it stands for DataBase Interface, and while it’s not part of the standard Perl distribution, it’s quite commonly used for database work in Perl.)

#!/usr/bin/perl


use DBI;
use CGI qw/:standard/;

$query = new CGI;
$order_number = $query->param('order_number');

$dbh = DBI->connect ("DBI:Oracle:MyDatabase");
$sth = DBI->prepare (<<"_QUERY_");
SELECT
parts.part_id, description, price,
order_number, quantity, shipped,
customers.name, customers.address
FROM parts, orders, customers
WHERE
parts.part_id = orders.part_id
AND
orders.customer_id = customers.customer_id
AND orders.order_number = $order_number
ORDER BY order_number
_QUERY_

$sth->execute;

print "Content-Type: text/html\n\n";

print <<_HEADER_;
<table>
<tr>
<th>Order<br>Number</th>
<th>Quantity</th>
<th>Shipped</th>
</tr>
_HEADER_

while ($row = $sth->fetchrow_hashref) {
print <<"_ROW_";
<tr>
<td>$$row{order_number}</td>
<td>$$row{quantity}</td>
<td>$$row{shipped}</td>
</tr>
_ROW_
}

print <<_FOOTER_;
</table>
_FOOTER_

$sth->finish;
$dbh->disconnect;

Before I show you the corresponding two objects that do the same thing under Zope, let’s take a whirlwind tour, for those of you who may not have worked with the DBI module, or do CGI interfacing in a different way, or whatever. The new CGI object in Listing 1 is just needed for its easy access to the parameters in the query. The $dbh is the database connection, managed by the DBI module, and the $sth is the statement handle. I prefer fetching data by name rather than by array position, so I always use fetchrow_hashref to retrieve a row at a time, after which the arcane hash deferencing notation with the double $$ is necessary, (if you haven’t seen that before). Also note that unless I use something else to do my headers (like Apache::Request) I have to print them myself. If you’ve ever forgotten that, you’ll know that it can be a real hassle to figure out what you’ve done wrong. (I make that mistake often enough that I look for it rather quickly, but the first time was a real pain.)

The output of this code will lack anything fancy like, oh, titles and stuff, but it will look something like this:

Order

Number Quantity Shipped

429873 42 40

429983 3 3

So let’s do the “same thing” in Zope, shall we? First thing to note is that under Zope the query is a separate object from the page. The query object looks like this:

SELECT

parts.part_id, description, price,
order_number, quantity, shipped,
customers.name, customers.address
FROM parts, orders, customers
WHERE
parts.part_id = orders.part_id
AND
orders.customer_id = customers.customer_id
AND orders.order_number = <!--#var order_number-->
ORDER BY order_number

That funny little <!–#var order_number–> is DTML, of course, and it gets replaced by the order_number from the query. Let’s assume we’ve saved this object under the name qryListOrderInformation, just as in the Zope documentation example. Then the page which uses that query object will look like this:

<table>

<tr>
<th>Order<br>Number</th>
<th>Quantity</th>
<th>Shipped</th>
</tr>

<!--#in qryListOrderInformation-->
<tr>
<td><!--#var order_number--></td>
<td><!--#var quantity--></td>
<td><!--#var shipped--></td>
</tr>
<!--#/in-->
</table>

So let me enthuse about this a little bit. The first thing that jumps out is the obvious one: there are two objects instead of one program. The first object tells the database what to deliver and can be built by a database administrator, while the second contains virtually no programming code and can very easily be built by a graphics specialist. In contrast, the HTML in the CGI program is interspersed within the code, and that leads to two things: first, the original version of the code, because it’s done by a programmer, will look really boring. Second, when graphics people look at it and realize it looks boring, they won’t have the nerve to change it, and it will stay boring forever. Naturally, our example looks boring anyway, because it was, well, done by a programmer — but you can easily extrapolate to real-world situations. Allowing delegation is a “Good Thing”. Heck, your graphics people can even use their WYSIWYG tools to do their part.

The second thing that jumps out (at me, anyway) is that the CGI example is indeed a program, and its listing is a lot longer than the two Zope objects. Amazingly, all the picky stuff in that program simply disappears in the Zope example, because the model presented is at a higher-level. The hard work is done for you already. Yeah, that theoretically takes some flexibility away from you. On the other hand, think back to the last time you needed flexibility in dealing with DBI. You didn’t need it, did you? In the Zope example, you have HTML to specify layout, and you have SQL to specify the query, and you don’t have all those hundreds of other typos waiting to happen. Thus you work more quickly. Much more quickly.

Note in the CGI program that you have that explicit DBI->connect and $dbh->disconnect . I know I already said this, but it takes a lot of work to do that. And what’s the first line of the CGI program? The explicit path of your Perl compiler. Ever had a really big collection of CGI scripts that you moved to another machine, which just happened to have installed Perl to a different location? I have, more than once. That problem won’t bother you with Zope, either. And see how the datasource is nicely buried in that code? Ever had to change Oracle SIDs at the drop of a hat? Guess what — Zope manages that, too.

The Real World Rears its Ugly Head

So when you actually need to get something done, should you pick CGI/Perl or Zope? For serious work, of course, you’re going to be writing serious code, or at least finding it somewhere. And since Perl and CGI have been around a while, you’re far more likely to find something useful in Perl than in Zope. That’s just reality, although time will tend to even out the difference. As far as writing your own code, I find it easier to code in Perl, while Python’s object orientation tends to force me to organize things better. I prefer Perl. In the long run, Python has to be more readable and more maintainable, especially in applications involving any kind of complex data structure (try typing ${$$cache{$object}}{$tag} three times fast, then try to read it next week), but I haven’t had enough experience to feel that difference in my gut yet.

For public release, you have another tradeoff, and a similar one. Every Web server and every Web host in the entire world supports CGI/Perl. Given the choice between a Perl solution and anything else, let alone Zope, I choose Perl for that reason alone. If, however, you will be specifying the environment, Zope is easier to install, easier to extend, and easier to package. It’s also more portable between Unix and Win32, if that’s a factor. Perl modules tend to resist porting to Win32, as the installation process relies heavily on the availability of the make program, and usually requires gcc as well. Getting Unix code to compile under Win32 can be done, but it’s not a trivial task, and as Perl doesn’t enjoy widespread acceptance among the Windows crowd, it’s not terribly likely that somebody has already ported your favorite module. Zope doesn’t have that problem, because it’s Python from the ground up.

When you really get serious about extending systems, you usually end up dropping down into C. And interfacing C with Perl just isn’t pretty, whereas interfacing C with Python is relatively easy. I think this is a consequence of the fact that Perl was originally conceived as a shell script replacement, thus it is great at working with external programs, pipes, files, and text (such as Unix shells), whereas Python grew out of the need to have a simple scripting glue for C libraries. C libraries are the whole point of Python. So if you’re writing C libraries for performance, Zope will probably be your choice.

So, is Zope Here to Stay?

I’ve mislaid my time portal, so this isn’t 100% sure, but I think the Zope community looks pretty strong, especially in Europe. The Zope philosophy is a good one, and I think it’s got carrying power. You may have heard the recent reports of system insecurity under Zope, but I suspect those problems will be ironed out rather quickly — open source is good for that. And frankly, the administration of user permissions under Zope is so much easier than under Unix that I think the end result will be better security rather than worse.

So yeah, I think Zope will be around for a while. It’s definitely going to be worth your while to download it and bang on it a little. Go on. You know you want to.

Resources

• Because Zope is a fast-moving community, you’ll want to check out the main Zope site, Zope.org. They have all the usual stuff there: downloads, lists of modules, latest news on what’s coming down the pike.

• The Python language Web site offers downloads, late developments, and documentation for the Python language. Python is also a fast-moving target, although it’s starting to mature.

Programming Python, by Mark Lutz (O’Reilly, 1996), ISBN 1-56592-197-6, is the programming language reference I use for Python. It’s more in a tutorial style than a reference, but it’s the best I’ve found and I can’t lift a finger without it.

• For another review of Zope, and an introduction, see Dev-Shed’s “Introduction to Zope”.

2010-05-26T17:03:17+00:00 April 30th, 2004|CGI and Perl|0 Comments

About the Author:

Michael Roberts has been slinging code for thirteen years but has only written about it for one. You can e-mail him at michael@vivtek.com or visit his Web site at http://www.vivtek.com. And the more the merrier.

Leave A Comment