znode: Zope for Filesystem-based Web Developers
Who this document is for
This is a document to help transition to Zope people who have experience in serving static web content from a filesystem. If you've run a simple web server and written a few HTML pages, perhaps using Server Side Includes to factor out headers and footers, you're in this audience.
This includes people who may have had pages hosted at
If you have experience with using scripts or something else to generate static content, this may be for you too, although the CGI and Scripting zNode may be more on target.
Coming from this background is actually a pretty good place from which to start with Zope, as you won't come with a lot of the ingrained concepts whose using other dynamic systems might.
How you used to do it
In the lowest level of web serving, there is only one layer and one level of translation. What web documents look like and contain is the same thing: an HTML document stored on the file system. To get this to the web, a web brower takes the URL it is asked for, strips its name off, and then looks in a specified place in the file system (the Document Root) for a file. If it finds it, it sends it to the requesting computer.
For example, say you have a file named
programs/apache/html/hello/world.html
on a computer
named www.test.com
with a Document Root of
programs/apache/html
.
If another computer asks
http://www.test.com/hello/world.html
then your computer
will stip off the http://www.test.com/
part, and look in
the Document Root for hello/world.html
. Since it is
there, the web server sends
programs/apache/html/hello/world.html
to the requesting
computer.
Server Side Includes
You may also be able to ask the server to do a little
processing on the documents before sending. If you were
to put the statement
<!--#include standard_footer.html-->
in a document, and set your server to process
SSI directives then it will try to include the contents of
the file standard_footer.html
in the same directory as
the document in the place of the directive. Zope often
seems to exhibit similar behaviour, with subtle but
distinct differences.
How Zope is different
When you first log in to Zope and look at the Zope Management
Interface, you might think you're looking at a representation
of a part of the file system, where the Zope folders are
directories, and the objects in them files. Even when looking
at the URLs used to access these objects it seems to do the
same thing as a regular web server. Looking at the index_html
file, it seems like Zope is doing some sort of server-side
include with a statement like <dtml-var standard_html_header>
.
But there is something strange afoot with Zope. Let's try a few experiments:
- Create a folder called
first
in the root folder. Select the option for Zope to create a public interface. (If you ask for a folder, and not a document, Zope will give you index_html, just like a regular web server will give you index.html under the same circumstances.)You'll end up with a folder called
first
with a document calledindex_html
in it. Looking atindex_html
you can see that it looks just like theindex_html
in the root folder. But there are no header and footer documents like in the root folder, and it looks like Zope is supposed to look for them in the current folder.View the front of your Zope site, and add
first
to the end of the URL. Nothing breaks. Where are the headers and footers coming from? - Go back to the root folder and make a DTML Method called
hello
. Add the textHello world!
to it. You can addhello
to the end of the base URL of your Zope site to see this document. Now addfirst/hello
to the URL. The page exists, and it says "Hello world!". But it doesn't exist in thefirst
folder. What exactly is going on?
Well, Zope isn't your average webserver. Zope uses a technique
called acquisition to create relationships between objects.
Most simply put, acquisition means that Zope objects contain
all the properties and objects that their parents contain.
So in our experiment above, the first
folder also contains
through acquisition all the objects that the root folder does
(including itself: try adding first/first/first/ to the URL)
which is why a document can include a local copy of
standard_html_header
if that object exists in a parent folder.
Acquisition doesn't keep you from adding properties and objects
to subfolders that have the same name as those in a parent
folders. If you were to create a different document named
hello
in the first
folder, then you would see that document
in first
and all its children rather than the one in
the root folder. As you can probably imagine, this can be
a very powerful technique when used properly, and terribly
confusing when misunderstood.
To fully understand the ramifications of this requires some understanding of Zope objects.
Objects
Everything you see in the Zope Management Interface is an object. Though the contents may sometimes look like files, they are not, but rather objects that contain data that looks like a file. But not only can objects contain data, they can also contain behaviours (called methods), which can change itself or other objects. For example, whenever you press the "Save Changes" button on a DTML Document, you're calling a method on that object that changes the contents to what was in the form.
There are two ways to describe Zope objects. One is whether or not they are folderish, and the other is whether or not they are methods.
Being folderish is pretty easy to understand. Either an object can hold other objects or not, rather like directories and files in a file system.
But objects can also be methods, in which case adding them to the folder allows you to add behavior to the folder, and through acquisition all objects it contains.
So what's the difference between methods and non-methods? Pretty simple: methods can contain their own data; they only have access to the data of the objects containing them. Why? A method is a behaviour, and behaviours cannot contain information. So if you ask a method about its properties, it will give you the properties of the folder it's being called from. Non-method objects can have their own properties.
This can be seen in the difference between DTML Documents and DTML Methods. Both contain behaviour for displaying themselves, but DTML Methods don't have properties.
What else?
I a regular old web server, the files are stored on the disk of the host system, but if you try to look around your Zope installation, you won't be able to find anything that looks like the structures you've made in Zope. Since Zope can be restarted and the objects don't change, they must be stored somewhere.
Zope objects are stored in the filesystem, but not in the
way HTML documents in a traditional web server are. Zope
comes with an object database (the ZODB) where Zope objects
are stored for persistence. Zope isn't particularly concerned
how the ZODB is stored, only how to interact with it, so that
there are many ways to store Zope objects. The default and
most common way is called File Storage, where the ZODB is
stored in a file called Data.fs on the file system in the
Zope/var/
directory.
What does this all mean?
That you can't think of Zope as just a webserver. Rather, it is a running application that is capable of representing the information of its contents as web documents.
On the surface, Zope looks a lot like a regular web server, but Zope has a much richer model. Because objects can do much more than files can, Zope provides much deeper functionality.
With Zope, you can have methods that provide different views on the same objects, you can provide logic in templates rather than just factoring out parts of files. Zope provides abilities that no webserver ever dreamed of.
When is static web serving better than Zope?
The answer is pretty obvious: when you're only serving static content, Zope is usually overkill. Although Zope can still provide a nice UI and versioning and undo capabilites, you should probably consider something like CVS instead.
Another situation is where speed is all that counts. Although Zope has been proven to be fast, serving static content is faster, since less calcuations need be done to get the page out the door. Usually this isn't the case, since if your site is heavily loaded you can add more servers, but if you're on a budget, need performance, and still want Zope, you could consider using Zope to generate static pages on a regular interval.
The Road to Zope Mastery
Obviously you're not going to be a Zope master overnight, and it'll take a while before the Zopeish thing to do is aparent. To get there from a plain old web serving, there are a few things to especially keep in mind:
- Zope objects are much richer than files and directories, and the interactions with objects are a lot richer than just including other files. You don't have to limit yourself to the way things are done in other systems.
- Make use of acquisition. Acquisition is your friend and a big part of the road to knowing Zope.
- Data can and should be separate from presentation. Don't even think about writing data into web pages. If nothing else it's a maintenance nightmare.
- Try to be clean. And try to design so that you can change the system without breaking things. Even better try to design so that you can change it without changing anything that's already there.
- Take advantage of the Zope mailing lists, the Zope.org Howtos, Zopelabs.com, and other resources.
- Learn to program, especially in Python. Zope makes an awful lot of sense once you start to think of it in programming terms, and you'll be able to do a lot more with it. Python is a beautiful language to learn programming with, and easy as anything.
- Last of all, start simple. You'll always be figuring out how to do things better, so don't screw up a big important site first: screw up a small simple site first.
Parting Words
This is how I started out with Zope, so I think I have the right perspective for this, but it's been a long time. If something's not clear or not there, email me. My address is at the bottom of the page.
Good luck Zoping.