This is an early draft chapter from a forthcoming book on Zope, to be
published by O'Reilly & Associates. The material has not been through
O'Reilly's editorial process, nor has it been reviewed for technical
accuracy. O'Reilly & Associates disclaims responsibility for any
errors in this draft and advises readers to use the information
contained herein with caution.
O'Reilly & Associates grants readers the right to read this material
and to print copies or make electronic copies for their own
use. O'Reilly & Associates does not grant anyone the right to use this
material as part of a commercial product or to modify and distribute
it. When O'Reilly & Associates publishes the final draft of this book
in print form, the content will be made available under an open
content license, but this chapter is not open content.
If you have any comments on the material in this chapter, you should
send them to the authors, Michel Pelletier and Amos Latteier, at
docs@digicool.com.
Building Basic Applications with Zope Objects
What are Zope Objects?
When you build a web application with Zope you construct it out of
objects. Different objects handle different parts of your
application. Some objects hold your data such as documents and images,
some objects control your logic such as form processing or sending
email, and some objects control your presentation such as page
templates.
In general Zope objects take three types of roles.
Content
Zope objects such as documents, images and files hold text
and binary data. Zope also has objects that connect Zope to remote
databases and allow you to retrieve and manipulate relational data.
Logic
Zope has facilities for scripting business logic. Zope
allows you to script behavior in Python, Perl, XSLT, and SQL. Your
application's logic in general is controlled by a number of method
objects that contain scripted behavior.
Presentation
You can control the look and feel of your site with
Zope objects that act as web templates. Zope comes with a tag based
scripting language that lets you produce dynamic HTML.
The word object is a heavily loaded term. Depending on your
background, it may mean many different things to you. In this chapter,
you can think of a Zope object as something that you can edit through
the web using the Zope management interface.
Zope comes with a many built in objects that help you perform different
tasks. You can install other third party Zope objects to expand Zope's
abilities. This chapter explains the most basic objects and how they
work. Using the few basic objects that we cover in this chapter you'll
be able to create fully functional Zope sites.
How do You Work with Objects?
When you get in someone else's car, it's pretty safe to assume you'll
know how to drive it. All though every car is different in terms of
performance, style and luxury, they all have a similar set of driving
controls that all do the same thing.
Zope objects have a similar sets of controls. Every kind of object
gives you a unique set of controls that you can use to mainpulate that
object. This unique set of controls is called an interface. Just
like the steering wheel, accelerator and brake pedal are the driving
interface to a car, so are various methods on an object an interface
do doing some sort of Zope task.
Your car provides you with a driving interface that directs the car
along the road. It also has other interfaces, like radio controls, that
let you change the music that you are listening to. In this case, the
car implements two familiar interfaces: one for driving and one for
listening to the radio. If you have power windows and power seats,
those are other interfaces that work to carry out specific tasks like
opening windows and moving your seat to a comfortable position.
Zope objects can also provide more than one interface for you to work
with. The interfaces that an object implements is documented in the
Zope online help system under "API Documentation":
<screenshot>
Here, we see the interface documentation for the Folder object. Other
interfaces that a Folder implements are listed as links at the top of
the page (XXX perhaps the help system should be more explicit about the
fact that these links are other interfaces that this object implements
-M)
Later in in this chapter you will see some pretty practical examples of
simple Zope applications. These examples are all constructed by
working with the various interfaces of Zope objects.
Folders
Folders are the building block of Zope. They are analogous to the
"folder" and "directory" metaphor used by most operating systems. The
purpose of a folder is to contain other objects, and to organize
objects by separating them into different groups.
Folders can contain all kind of objects, including other folders. This
lets you nest folders inside each other to form hierarchical, or tree,
structures. This kind of folders within folders arrangement provides
your Zope site with structure. Zope cares quite a bit about folder
structure. As we'll see through out the book almost all aspects of Zope
from security to behavior to presentation work are formed by your
site's folder structure. For this reason, the humble folder is the
most useful and powerful object in Zope.
How you organize objects in Zope folders is very important. Good
folder organization will make using Zope very easy and powerful,
but by the same token bad folder use can result in confusing or
difficult to manage applications. Learning how to best take
advantage of folder organization in your application takes time
and experience. It is part of what is sometimes called the "Zen"
of Zope.
Managing Folder Contents
In Chapter 1 we covered how to create objects and move them
around. To re-cap, you create objects in a folder by choosing the
name of the object from the pull down menu at the bottom of the
folder's "Contents" view. Then fill out the add form and submit it. A
new object will be added to the current folder. You can move objects
between folders using the cut, copy, paste, and rename controls.
Importing and Exporting objects
So you know how to move objects around in Zope, what about moving
objects between different Zope servers? Zope allows you to do this
with its import and export facilities. You can export all types of
Zope objects to an export file. This file can then be imported
into any other Zope system. This is allows you to move objects
from one Zope to another.
You can think of exporting as cloning a piece of your Zope system
into a file you can move around from machine to machine. You can
then take this file and graft the clone onto any other Zope.
Imagine you had a few thousand documents in a Zope folder. If you
wanted to copy just those objects to your friend's Zope system, you
could export the folder and send the file via email to the friend,
who could then import it.
Suppose you have a folder for home work that you want to export
from your school Zope and take home with you to work on in your
home Zope. Go to folder that contains your homeWork
folder. Select the homeWork folder by checking the checkbox next
to it. Then click the Export ... button. You should now be
working in the Import/Export folder view.
There are two sections to this screen. The upper half is the
Export section and the lower half is the Import section. To
export an object from this screen, just type the id of the object
into the first form element, Export object id. In our case Zope
already filled this field in for us, since we selected the
homeWork folder on the last screen.
The next form option is whether you want to download the export
file to your computer or leave it on the server. If you check
Download to local machine, and click the Export button, your
web browser will prompt you to download the export file. If you
check Save to file on server, then Zope will simply the save the
file on the same machine that Zope is running on an you must fetch
the file from that location yourself. The export file will be
written to Zope's var directory on your server. In general it's
handier to download the export file to your local machine.
Sometimes it's more convenient to save the file to the server
instead, for example if you are on a slow link and the export file
is very large.
The final export form element is the XML format? checkbox.
Checking this box will export the object in the eXtensible Markup
Language (XML) format. Leaving this box unchecked will export the
file in Zope's binary format. The XML format is much bigger to
download, but is human readable and XML parsable. For now, the
only tool that understands this XML format is Zope itself, but in
the future there may be tools that understand Zope's XML format.
In general you should leave this box unchecked unless your curious
about what the XML format looks like and you want to examine it by
hand.
Click the Export button and save your homeWork.zexp export
file.
Now suppose that you've gone home and want to import the file into
your home Zope. First, you must copy the export file into the
import directory of your Zope installation. This may seem
tedious, but Zope will not let you upload an export file to since
this would be a huge security hole. By requiring that you copy the
import file to the server's import directory, Zope insures that
you are a trusted user.
Once your export file is in the import directory of your Zope. Go
to the Import/Export view of the folder where you want perform
the import. Enter the name of the export file in the Import file
name form element and click Import to import those objects into
Zope.
Zope gives you the option to either Take ownership of imported
object or Retain existing ownership information. Ownership will
be discussed more in Chapter XXX, so for now, just leave the Take
ownership button checked.
After you import the file you should have a new object in the file
where you performed the import.
To bring your homework back to school, perform the same export and
import procedure. Note that you can't import a object into a folder
when then there is an existing object with the same id already in
the folder. So when you bring your home work back to school you'll
need to import it into a folder that doesn't already have a
homeWork folder in it. Then delete your old homeWork folder and
copy the newly imported one into its place.
Properties
Properties are ways of associating information with objects in
Zope. Many Zope objects support properties including folders and
documents. Properties can label an object to identify it's contents
(many Zope content objects have a content-type property). Another
use of properties is to provide meta-data for an object such as it's
author, title, status, etc.
Properties can be more complex than strings; they can also be
numbers, lists, or other simple data structures. All Properties are
managed via the Properties view. Click on a folder's Properties
tab and you be taken to the properties management view.
All properties consist of a name and a value. Properties also have a
type. The type of a property defines what kind of values a property
can have.
In figure XXX you can see that the folder has two properties. One is
named "Author", and the other is named "KeyWords". The "Author"
property is a "string", while the "KeyWords" property has a type of
"tokens".
Property Types
string
A string is an arbitrary length sequence of characters.
Strings are the most basic and useful type of property in Zope.
int
An int property is an integer, which can be any positive or
negative number that is not a fraction. An int is guarenteed at
least 32bits of precision.
long
A long is like an integer that has no range limitation.
float
A float holds a floating point, or decimal number.
Monetary values, for example, often use floats.
lines
A lines property is a sequence of strings.
tokens
A tokens property is a string that is broken up into a
sequence of strings at whitespace boundaries.
text
A text property is just like a string property, except that
Zope normalizes the line ending characters (different browsers use
different line ending conventions).
selection
A selection property is special, it is used to render
an HTML form input widget.
multiple selection
A multiple selection property is special, it
is used to render an HTML form input widget.
Creating a Simple Property - Example
Simple string properties are useful for giving a name to a string
value. A good example is the name of a company. Given the way
companies are bought and sold, it could be very useful to have a
property called company_name that you can use throughout your
site to print out the name of your company. When the company gets
bought, you only need to change the value of the one property,
instead of changing the name all over your site. In this way,
properties let you factor simple content.
Click on the Properties tab to go to the Properties View of the
current folder.
Make sure that the type of property is string and and give the
new property the name company_name and he value Avuncular Bobs
and Floation, Inc..
To use the new property, create a DTML Document called "ABF" with
the following content:
<dtml-var standard_html_header>
<h1>Welcome to the <dtml-var company_name> Web Site</h1>
<dtml-var standard_html_footer>
Now view the document by clicking the View tab. You can use the
assertion anywhere in your Zope site.
Documents
Documents hold text. In web applications you generally use documents to
create web pages. You can also use documents for text files or for
snippets of text or HTML such as sidebars or headers. In addition to
containing text, the chief function of a document is to allow you to
edit the text through the web.
Zope has two different types of documents.
DTML Document
is the workhorse document. Use it to create web
pages and sections of content such as a sidebar that are shared by
web pages. DTML documents can contain scripting commands in DTML
Zope's tag based scripting language. By mixing HTML and DTML you can
generate dynamic web pages.
XML Document
holds XML content. Use XML Documents when you want to
query and transform XML.
Other document types are available as Zope add-ons to allow you to
manage other types of text.
In this chapter, we will explore the most common kind of document,
DTML Document.
DTML Document
You can use DTML Document for creating dynamic web pages. Their
purpose is to hold some amount of content and to manipulate that
content for dynamic presentation. DTML Documents can transform their
content with the Document Template Markup Language (DTML) scripting
language.
DTML Documents are also useful for creating shared content, such as
common document structures.
Adding DTML Documents
Create a Folder called Sales in the root folder. Then, click on
the Sales folder and then select DTML Document from the add list
you worked with in Chapter 1. This will take you to the add form
for a DTML Document:
<screenshot>
Specify the id SalesStaff and the title The Jungle Sales
Staff and click Add.
There is another form element for uploading a file, this will be
discussed later on in this section.
Editing DTML Documents
The easiest and quickest way to edit a DTML Documents is through
the web management interface. To edit a document, click on its name
or icon:
<screenshot of SalesStaff>
This icon shows a text area where you can edit the content of the
document. Clicking on the Change button will make effective any
changes you made in the text area. You can control the size of the
text area with the Taller, Shorter, Wider, Narrower
buttons.
Delete the default content inside the DTML Document.
Add the following HTML content to the SalesStaff document:
After you are done making changed, click the Change button. Zope
returns with a message telling you that your changes took effect.
Now, you can look at the document by clicking the View tab.
Congratulations you've used Zope to create an HTML page. You can
edit you HTML on line and view it immediately. In fact, you can
create entire Zope sites of HTML documents and folders. This
wouldn't give you many of Zope's benefits, but it could be a good
way to get familiar with Zope. You could also write some dynamic
stuff in Zope and then let other folks who didn't want to learn
about Zope's power create and edit their own HTML web pages like
this.
Upload an HTML File - Example
Suppose you don't want to edit your HTML files in a web browser,
or you already have some HTML pages that you'd like to bring into
Zope. Zope allows you to upload existing text files into DTML
Documents.
Select Add DTML Document from the add menu, this will take you
to the add form for DTML Documents. The last form element on the
add form is a Choose File button. Click this button. Your
browser will pop up a file selection dialog box. Select the text
file on your computer that you want to upload to this document.
It's important to note that you must almost always specify an id
for a new object that you create. In this case however, Zope
will use the filename of the file you upload as the objects id.
You can override this behavior by specifying a value for id in
the add form. For now, you can just choose a file and leave the
id and title fields blank.
After clicking Add, you will be taken back to the management
screen and the document you uploaded will be in the folder you
added the document to.
If you already have a DTML Document you can replace it's content
with an uploaded file by going to the Upload tab.
Remote editing - FTP, WebDAV, and PUT
Zope let's you edit document directly in your web browser, but
this is not the only way documents can be edited in Zope. For
simple documents, editing through the web may be handy, but web
browsers are not meant to be modern, advanced text editors. For
large, complex documents, or documents in special formats, it
would be nice if you could use the editor you are most used to.
DTML Documents can be edited with FTP, WebDAV, XML-RPC and the
HTTP PUT protocol. Many HTML and text editors support these
protocols for editing documents on remote servers. Each of these
protocols has it's own advantages and disadtantages:
FTP
FTP is the File Transfer Protocol. FTP is used to
transfer a file from one computer to another. Many text
editors support FTP, so it is very useful. FTP does not
understand many of the same semantics as editing through the
web however, like properties and working with objects that are
not document like.
WebDAV
WebDAV is a new internet protocol based on the same
underlying protocol as the Web, HTTP. DAV stands for
Distributed Authoring and Versioning. Because DAV is new, it
may not be supported by as many text editors as FTP. Because
it is based on HTTP however, it supports much richer semantics
for working with Zope objects.
PUT
The HTTP protocol supports a simple way to upload
content to a server called PUT. PUT is very simple and is
supported by many HTML editors like Netscape Composer.
XXX xml-rpc? -M
WS_FTP - Example
WS_FTP is a popular windows based FTP client. WS_FTP can be
downloaded from the Ipswitch Home
Page.
In Chapter one, you figured out the URL to your Zope system by
looking at the start up log. Finding out how to contact your
Zope's FTP server is very similar:
------
2000-08-07T23:00:53 INFO(0) ZServer Medusa (V1.18) started at Mon Aug 7 16:00:53 2000
Hostname: peanut
Port:8080
------
2000-08-07T23:00:53 INFO(0) ZServer FTP server started at Mon Aug 7 16:00:53 2000
Authorizer:None
Hostname: peanut
Port: 8021
------
2000-08-07T23:00:53 INFO(0) ZServer Monitor Server (V1.9) started on port 8099
The startup log says that the Zope FTP server is listening to
port 8021 on the machine named peanut. When you start
WS_FTP, you will need to know those two peices of information
so you can connect to Zope with FTP:
<screenshot of WS_FTP connect screen>
After typing in the connection information, hit the Connect
button. WS_FTP will now ask you for a username and password.
Enter the same managment username and password that you use for
the Zope managment interface:
<screenshot?>
If you type in the right username and password, WS_FTP shows
you what your Zope site looks like through FTP. In Figure XXX,
you see that there are folders and documents that corespond
exactly to what your root Zope folder looks like through the
web.
Transfering files to and from Zope is very easy with WS_FTP.
On the left hand side of the program is a file selection box
that represents files on your local machine. The file
selection box on the right represents objects in your Zope
system. Transfering files from your computer to Zope or back
again is as easy as selecting the file you want to transfer and
clicking either the left arrow (download) or the right arrow
(upload):
<screenshot of upload>
WS_FTP has lots of cool features and customizations that you
can use to make remote object managment with Zope very easy.
For more information on these features, see the WS_FTP help
system or read the documentation at the Ipswitch home page.
Emacs FTP - Example
Emacs is a very popular text editor. Emacs is more than
just a text editor, it is a whole culture. Emacs comes in
two flavors, GNU Emacs and XEmacs. Both of these flavors
of Emacs can work directly over FTP to manipulate Zope
documents and other textual content.
If you are a more advanced user this becomes incredibly
powerful. Emacs will let you treat any remote FTP system like
any other local filesystem, making remote management of Zope
content very easy. You don't have to leave Emacs to use Zope.
Emacs provides much richer text editing capabilities than
web browser text areas. Emacs can be used to directly
edit Document and Methods through FTP, thus making Emacs a
simple Zope IDE.
By default when you start up Zope, Zope runs an FTP server just
like it runs an HTTP server. You can specify when you start
Zope which port it's FTP server should listen on, but by
default this port is 8021.
To log into Zope, run Emacs. Which file to visit to open an
FTP connection depends on whether you are running XEmacs or
Emacs:
Xemacs
To visit a remote file in XEmacs, visit a file by
the form::
/user@server#port:/
This will open a connection to the / folder of the FTP server
running on server and listening on port port.
Emacs
To visit a remote file in Emacs, visit a file by the
form::
/user@server port:/
The literal space is inserted by type holding down the
Control key and the Q key, and then pressing the space.
So, "C-Q ".
For the typical Zope installation with XEmacs, the filename to
open up an FTP session with Zope would be
/user@localhost#8021:/.
Emacs will ask you for a password to log into Zope's FTP server.
Visiting the / folder of an FTP server in Zope, Emacs will list
the contents of the root folder:
drwxrwx--- 1 Zope Zope 0 Dec 30 1998 Control_Panel
drwxrwx--- 1 Zope Zope 0 Dec 30 1998 QuickStart
drwxrwx--- 1 Zope Zope 0 Dec 30 1998 Sales
-rw-rw---- 1 Zope Zope 1024 May 3 1999 index_html
-rw-rw---- 1 Zope Zope 1381 May 3 1999 standard_error_message
-rw-rw---- 1 Zope Zope 55 Dec 30 1998 standard_html_footer
-rw-rw---- 1 Zope Zope 81 Dec 30 1998 standard_html_header
You can visit any of these files (which are really Zope
objects) by selecting them in the usual Emacs way.
History
The Undo tab lets you undo one transaction at a time, but
often it is useful to undo only the change to one object.
To do that, you can go to that object's History View and
look at the previous states of the object:
<screenshot>
Some objects may even support the idea of comparing two
revisions, letting you can track changes to your objects. For
example, DTML Methods and Documents will allow you to select two
revisions and compare them to one another:
<screenshot>
This information is in a popular format called diff. The
diff shows you which lines were added to the new document
(marked with a plus), which likes were taken away from the
old (marked with a minus), and which lines were replaced or
changed by different ones (marked with an exclamation
point).
Viewing DTML Documents
DTML Documents can be viewed several different ways:
Management Interface
From the management interface you can
Click on a Documents View tab to view the contents of the
document.
Calling Directly Through the Web
Documents can be called
directly through the web by going to their URL location with a
web browser.
Called by Another Object
Other objects, especially other DTML
objects, can use a Document's content.
Calling through the Web
Like all Zope objects, a DTML Document's URL is based on it's
id. For example, if you had a DTML Document in the root folder
called Bob, then it's URL would be:
http://localhost:8080/Bob
If Bob was in a sub-folder called Uncles then it's URL would
be:
http://localhost:8080/Uncles/Bob
There could also be other DTML Documents in the Uncles folder
called Rick, Danny and Louis. You access them through the
web similarly:
Translating URLs to objects isn't a new idea, web servers like
Apache do it all the time, they translate URLs to files and
directories on a filesystem. Zope carries this simple idea over
into a whole new object oriented world. In Zope, URLs are
allways simple to read because they map easily and simply onto
the way objects are organized in Zope. This is why we told you
that your site's structure was very important in the previous
section on folders.
Going directly to the URL of a DTML Document is called calling
it through the web. This causes the content of the DTML
Document to be evaluated and retured to your web browser. In the
next chapter on DTML, we will see what it means for DTML to be
evaluated, but for now, you can easily experiment with DTML and
simple HTML content to get the idea.
Calling from another Object
Several times throughout this chapter you have seen the following
code:
<dtml-var standard_html_header>
<h1>This is some simple HTML</h1>
<dtml-var standard_html_footer>
What this means is explained in much more detail in the next
chaper, but here we see that one DTML object,
standard_html_header is being called by the document that
contains this code. In this case, the contents of the first
document are inserted into the contents of this document. This
is an very fundamental concept in Zope and will be used almost
contantly throughout the rest of this book.
Methods
Methods define application behavior. Methods let you
create dynamic content in Zope by scripting in a number of
languages.
Almost every type of web application there is needs some sort of
scripting feature. Zope is fairly unique in that it does not provide
just one or two kinds of scripting languages, but several.
Zope gives you a couple different types of methods.
DTML Method
is the workhorse method. use it to script simple web
pages and sections of behavior, and to glue various Zope API methods
together to form useful functions.
SQL Methods
query relational databases with the Simple Query
Language (SQL). SQL Methods lets you write SQL code directly into
Zope through your web browser.
Python Methods
allow you to write python code directly into Zope
through your web browser. Python is a powerful object oriented
language and is Zope's native language; most of Zope is written in
it.
Perl Methods
allow you to write Perl code directly into Zope
through your web browser. Perl is a very popular programming
language with powerful text manipulation semantics.
External Methods
let you execute python code on the filesystem
which is considered outside or external to Zope. External Methods
are useful for hooking existing python code into Zope without
re-engineering your code.
XSLT Methods
let you query and transform almost all Zope objects
that support the Document Object Model (DOM). XSLT is a very
powerful standard language for working with DOM and XML.
In this section, we will explore the most common kind of method, DTML
Methods.
DTML Methods
All the various objects in Zope can be manipulated by calling methods
on those objects. DTML Methods can be used to write simple scripts
that call the assorment of methods that make up the Zope API. The
API is documented in the Help System, under API Documentation.
A simple example of this is creating a DTML in the the root folder
called objectList:
When you view this method, it will call the objectValues method on
the root folder and this will show you a simple HTML list of all the
objects in the root folder:
<screenshot>
All folders implement the objectValues method. The objectValues
method is part of a common interface that all Folders implement
called the ObjectManager interface.
In addition to calling API methods on objects, DTML Methods can also
be a method on any Zope object. This allows you to extend the API
of Zope by simply creating DTML Methods in or above the folders you
want to use them in. In the above example, you used the allObjects
method, which is in the root folder, to make a simple list of the
contents of the root folder.
Because the method is in the root folder, it is now usable by any
other objects below the root folder. This, in effect, is now an
extension of the Zope API. A good example is to create a subfolder
called "Primates" and add three documents, "Monkeys", "Apes",
"Humans":
<screenshot>
Now, you can see the effect of calling the objectList method on the
Primates folder:
<screenshot of http://localhost:8080/Primates/objectList>
The objectList method is defined in the root folder, but here we
are using it to display the contents of the Primates folder. This
mechanism of reusing objects is called acquisition and will be
explained more in Chapter XXX.
DTML Methods serve two purposes:
Templates
Methods that act as templates allow you to tie reusable
bits of content together into a dynamic presentation. The templating
features of DTML Methods will be discussed in further detail in the
next chapter.
DTML Scripting
DTML support of conditional statements, iteration
(looping) and function calling make it a useful general purpose
language for scripting Zope.
Comparing DTML Documents and Methods
DTML Methods have the exact same user interface as DTML Documents,
which can be a bit confusing to the beginner. All of the procedures
that you learned in the last chapter for adding, editing, viewing and
uploading DTML Documents is identical for DTML Methods.
A frequent confusion for Zope beginners is when to use a DTML
Documentg and when to use a DTML Method. On the surface, they seem
identical. They both hold DTML and other content, they both
execute DTML code, and they both have a similar user interface and
a similar API, so what's the difference?
DTML Documents are meant to hold document-like content. For
example, the various chapters of a book could be held in a DTML
Document. A a general rule, if your content is mostly document
like and you want to present it on your site, then put it in a DTML
Document.
DTML Methods are meant to manipulate and work with other objects.
DTML Methods don't often hold lots of content themselves unless
that content is meant to change or manipulate other content in
Zope.
Don't worry if you're still unclear what the different between DTML
Document and Methods are. Even the best Zope programmers still
need to think a little when deciding what kind of object to use.
Here are some general rules to help you make up your mind when
deciding to use a DTML Document or Method:
If it's content, then it's a DTML Document.
If it's behavior, then it's a DTML Method.
If it's meant to be presented by other objects, then it's a
DTML Document.
If it's meant to present other objects, then it's a DTML
Method.
Files
Zope Files containers of raw data, just like files on your
computer. Lots of information, like software, audio, video and
documents are transported around the Internet and the world as
files. You can use files to hold any kind of information that Zope
doesn't specifically support, such as Flash files, applets,
tarballs, etc.
Using Files
Files do not consider their contents to be of any special format,
textual or otherwise. Files are good for holding any kind of binary
content which is just raw computer information of some kind.
All File objects have a Content-Type which is a standard
Internet MIME designation for file type. When you upload a file
Zope will try to guess the content from the name of the file,
but this might not work if the file does not have an extension
that Zope recognizes.
Example - Uploading Content
Like DTML Documents and Methods, Files have an Upload option on
their add for that lets you upload file content into the object.
To upload new content into a File when it is created, click on the
Choose File button:
<screenshot>
Try choosing a file like a Word Document (.doc) or a Portable
Document Format (.pdf) document. After selecting a file to upload,
click Add. Depending on the size of the file you want to upload,
it may take a few minutes to add the file to Zope.
After adding the file, select the file and look at it's
Properties view. Here you will see that Zope guessed the Content
Type of the file you added. If you add a Word document, the
content type should be application/msword. If you chose a PDF
Document, the content should be application/pdf. If Zope does
not know what kind of file you uploaded, it will choose the
default, generic content type of application/octet-stream:
<screenshot of properties with content type>
Files can be viewed in Zope by pointing a web browser directly at
their URL. For example, if you have a file in your Zope root folder
called employeeAgreement.pdf then you can view that file in your
web browser by going to the URL
http://localhost:8080/employeeAgreement.pdf.
Images
Images display graphics such as GIF, JPEG, and PNG files. In Zope
images are similar to File objects, but include extra behavior
that makes them more appropriate for managing graphic content.
Images have the same management interface as file objects.
Everything in the previous section about using file objects also
applies to images.
Using Images in DTML
Viewing Images with HTML
The most common use for Images in Zope is putting pictures in web
pages. To put a picture in a web page, you have to use the HTML
tag. Suppose you had an image object in your root folder
called logo that contains an image of your organizations logo:
<screenshot of image file in root folder>
Using this image in your HTML is easy, you can reference it with an
tag just like any other kind of HTML:
<dtml-var standard_html_header>
<img href="logo"><br>
<h1>Welcome to the Zope Zoo!</h1>
<dtml-var standard_html_footer>
In this example, you referenced the logo image by creating an HTML
tag., but usualy it is not necessary to create your own IMG
tags to display images. Image objects know how to generate their
own HTML tags. When you insert an image object in DTML, it
generates a tag for itself.
Now, we want this logo to be seen on every page up in the left hand
corner, so put a reference to it in your standard_html_header
method:
<html>
<body>
<dtml-var logo>
Now, view the root folder by clicking on the View tab. If you
look at the source to the web page that gets created, you will see
that the tag was turned into an HTML tag
for you:
As you can see, using the tag to draw images is easier
because Zope figures out the "height" and "width" tag
attributes for you.
Viewing images through the web
Images can be viewed directly by going to their URL in Zope. For
example, say you wanted to view your company logo directly. If it
is an image object in your root folder called logo, you can view
it by going directly to it's URL:
<screenshot of http://localhost:8080/logo>
This is very useful for storing lots of images in one of your Zope
servers for use by other servers. This is a common pattern for
high volume sites, by putting all of your images on a different
server, you spread the load of your site around to a couple
different machines. For example, let's say you had a machine named
images.zopezoo.org and it had a folder in the root directory
named Images that had all the various pictures you use on your
Zope site. From another machine (running any kind of web server)
you could references those images by using their URL:
<html>
<body>
<p>Here are some animals in the Zope Zoo:</p>
<ul>
<li><img href="http://images.zopezoo.org/Images/baboon.jpg"></li>
<li><img href="http://images.zopezoo.org/Images/parakeet.jpg"></li>
<li><img href="http://images.zopezoo.org/Images/catdog.jpg"></li>
</ul>
</body>
</html>
Putting It All Together
Using the basic objects described in this chapter you can easily build
a simple web application.
Building Applications with Folders and Methods
We've said that Folders are the "basic building blocks" of Zope
applications. Folders add structure, but their real power comes when
you also give them behavior with methods.
Methods and folder work together to build simple applications.
Folders not only provide structure for your information, but they
also provide structure for your sites behavior. Later in this
chapter, we give an example of a simple guestbook application based
on this design concept. A folder is used to hold the methods and
data of the guest book application.
Methods in folders are generally given names that describe their
function. For example, if you had an Invoices folder, you might
have methods inside that folder named addInvoice and editInvoice.
This turns the Invoices folder into a small application. You can
then use Zope's simple URL to object translation to work with the
application, for example, http://localhost:8080/Invoices/addInvoice
will take you to a screen that lets you add an invoice.
http://localhost:8080/Invoices/editInvoice?invoice_number=42 could
allow you to edit invoice number 42.
There is one special object name in folders called index_html.
This special name is the default view of the Folder. For example,
if you put an index_html method in your Invoices folder and viewed
the Folder by clicking the View tab or by visiting
http://localhost:8080/Invoices/, the method or object with the
index_html will be used to display the folder. The reason for this
name is historical more than logical. In general, any object with
the id index_html can be considered the default view for the
current Folder that it is in.
The Zope Zoo
In this section, you'll create a simple website for the Zope Zoo. As
the Zoo webmaster, it is your job to make the website easy to use and
manage. Here are some things you'll need:
Zoo users must easily move around the site, just like if they
were walking through a real Zoo.
All of your common web layout, like a Cascading Style Sheet
(CSS), must be in one easy to manage location.
You must provide an easy to manage file libary of various
documents that describe the animals.
A SiteMap must be provided so that users can quickly get an
idea of the whole layout of the Zoo
A Guestbook must be created so that Zoo visitors can give you
feedback and comments about your site.
A whats new section must be added to the guestbook so that you
can see any recent comments that have been added.
Example - Navigating the Zoo
First, in order for your navigation system to work, your site needs
some structure to navigate around in! Create some folders in your
Zope system that represent the structure of your site. For our
examples, we'll be using a Zoo structure with the following
layout:
The main structure of the Zope Zoo are three top level Folders,
Reptiles, Mammals and Fish. To naviate your site, users should
first go to your home page and be able to click on one of the top
level folders to go to that particular part of the Zoo. Once they
have steped into a top level area, like Reptiles, they should be able
to use a very similar interface to keep going deeper, like the Snakes
section. Also, the user should be able to back out of a section
and go "up" to the parent section.
Sound complicated? This is very trivial in Zope. In your root
folder, create a DTML Method called navigation:
This method prints a list of links to the various sub-sections of
whatever particular part of the Zoo you are in. Now, we need to put
this method somewhere were users will allways see it. Let's put a
reference to it in the standard_html_header object so that the
navigation system is available on every page of the site. Your
standard_html_header could look like this:
Now, we also need a front page that serves as the welcome screen
for Zoo visitors. Let's create a DTML Method in the root folder
called index_html with the following content:
<dtml-var standard_html_header>
<h1>Welcome to the Zope Zoo</h1>
<p>Here you will find all kinds of cool animals.</p>
<dtml-var standard_html_footer>
Now, take a look at what your site looks like by cliking on the
View tab in the root folder:
<screenshot>
Here you start to see how it all comes together. At the top of your
main page you see a list of sub-links to the various subsection.
Remeber the structure of your folders? Here they are:
<screenshot>
Click on Reptiles. This takes you to the view of the Reptiles
folder. Because this view is sharing the same standard_html_header
as the root folder view, it acquires the same navigation method
interface, but this time the interface shows you the sub-sections of
the Reptiles folder:
<screenshot>
Later on we'll see how this ability to acquire interfaces works, for
now, you can think of the navigation method as being an extension
to the Zope API that you created.
This example shows how content can by dynamical generated from a
script. The script lists all the objects in a certain folder in an
HTML list. This script is written in DTML. Don't worry too much
about how to use the language yet, DTML will be explained in detail
in the next chapter.
Factoring out CSS Content - Example
The standard_html_header is a pretty useful method. In the last
example, we saw how it let you factor out the behavior of calling the
navigation DTML method for all the pages on your site.
In addition to factoring out behavior, the standard_html_header can
also factor out content. For example, create a DTML Document in your
root folder called default_style_sheet:
<style type="text/css">
P { color: #ff0000 ; font-size: 18px }
</style>
This is a Cascading Style Sheet. This
style sheet asserts a style definition for HTML paragraphs. To make
this assertion effect your entire website, just edit your
standard_html_header file like this:
Now, when you look at documents on your site, all of their paragraphs
will be red. Why lacking any kind of style, this example does show
you how to factor out common content structures like style sheets
throughout your site (perhaps we need a more interesting sheet? -M)
File Library - Example
File libraries are common on web sites since many sites distribute
files of some sort. The old fashioned way to create a file library
was to upload your files, then create a web page that contained links
to those files. It would be better if Zope generated all of those
links for you; when you uploaded a new file, the link is created
dynamically.
Create a folder in the root folder called Files. This folder will
contain all of the file you want to distribute to your web visitors.
In this Folder, create some empty file objects called Reptiles,
Mammals, and Fish.
DTML can help you save time maintaining this library:
Now view the method. Here, you can see this method prints you a
simple HTML list of your file libary. If you add another file, Zope
wil dynamcally generate a new listing for you.
GuestBook - Example (XXX the example code here is only roughed out -M)
A Guest Book is a common and useful mini web app so that visitors to
your site can sign your guestbook. Here is an example of a very
simple guestbook written in Zope:
<screenshot of display method>
First, create a folder called GuestBook that will hold all of your
guest book entries. Give this folder the title The Zope Zoo
Guestbook. This is a good example of how Folders are used to
organize your application.
A Zope GuestBook can be done several ways, but for this example, we
will pick one of the simplest. The GuestBook folder will hold a
bunch of DTML Documents, one document for each guestbook entry. When a
new entry is added to the guest book, a new document is created in the
GuestBook folder. To delete an unwanted entry, just go into the
GuestBook folder and delete the unwanted document using the management
interface.
The first task for the guest book should be a method that displays
all of the entries. Call this method index_html so that it is the
default view of the GuestBook folder:
<dtml-var standard_html_header>
<h2><dtml-var title_or_id></h2>
<ul>
<dtml-in expr="objectValues('DTML Document')">
<!-- iterate over each DTML Document in the folder -->
<dtml-if expr="hasProperty('guestbook_entry')">
<!-- if the document has the 'guestbook_entry' then print
time the comment was made, who made it, and then the
comment -->
<li>On <dtml-var bobobase_modification_time>,
<dtml-var guest_name html_quote> said:<br>
<dtml-var sequence-item html_quote></li>
<!-- make sure we html_quote so the users can't sneak any
HTML onto our page -->
</dtml-if>
</dtml-in>
</ul>
<!-- provide a link to add a new entry, this link goes to a form -->
<a href="addEntryForm">Sign GuestBook</a>
<dtml-var standard_html_footer>
This method displays a bulleted list of guestbook entries.
You must create a form that you site visitors can use to add new
guestbook entries:
When a user submits the form above, the action says the URL
addEntry will be POSTed to with the form information. To handle
this form information, create a DTML Method called addEntry.:
Once again, don't concern yourself too much with the details of what
this code does. This method creates a new DTML Document in the
GuestBook folder and sets two new properties on that document
guest_name and guestbook_entry. guest_name is the name of the
guest and guestbook_entry is a flag that says this DTML Document is
a guestbook entry. Lastly, the method thanks the entry subitter and
gives them a link to go back to the guestbook.
That's it! To use the simple guest book, just visit
http://localhost:8080/GuestBook/.
What's new - Example
Frequent visitors to your site may want to see only the newest
guestbook entries on your site. Let's see what new guestbook entry
were added in the last 24 hours:
First, let's put a link to the what's new feature on every page.
To do that, we change our standard_html_header yet again:
This method displays a link to all of the guestbook entries less than
one day old. Here we can see that DTML can do some pretty powerful
stuff. Here we see that our whats_new method has a lot in common
with our index_html method. Can they be combined into one? Sure!
Delete or move out of the way the what's new method. First, let's
change our standard_html_header yet again:
The difference is subtle, can you spot it? Since the whats_new
method is no longer needed, we don't link to it in the second link,
instead, a special flag is set called whats_new. This flag is given
the value of 1. Now, let's change the index_html method just a bit:
<dtml-var standard_html_header>
<h2><dtml-var title_or_id></h2>
<ul>
<!-- find all the guestbook entries -->
<dtml-in expr="objectValues('DTML Document')">
<dtml-if expr="hasProperty('guestbook_entry')">
<!-- if the whats_new flag exists, then see if the entry is
younger than one day -->
<dtml-if whats_new>
<dtml-if expr="bobobase_modification_time < ZopeTime() - 1">
<!-- if it is a new one, print a little 'New!' label next
to it -->
<li><b>New!</b> - <a href="&dtml-absolute_url;"><dtml-var title_or_id></a></li>
</dtml-if>
<dtml-else>
<!-- if there's no what's new flag, just print a link -->
<li><a href="&dtml-absolute_url;"><dtml-var title_or_id></a></li>
</dtml-if>
</dtml-if>
</dtml-in>
</ul>
<a href="addEntryForm">Sign GuestBook</a>
<dtml-var standard_html_footer>
Do you see the difference here too? You can ask Zope to show you the
different on the History view for the index_html method. Click the
History tab and select the top two items, then click compare:
<screenshot>
Zope is showing you what change, we added an else clause to our
if tag that changes the behavior of the method depending on the
precense of whats_new. This is some pretty advanced DTML, and to
new eyes it looks tricky, but it's really pretty simple, and in the
next chapter we'll show you some basic DTML concepts that explain our
examples in detail.
Copyright O'Reilly, 2000. All rights reserved.
This is an early draft chapter from a forthcoming book on Zope, to be
published by O'Reilly & Associates. The material has not been through
O'Reilly's editorial process, nor has it been reviewed for technical
accuracy. O'Reilly & Associates disclaims responsibility for any
errors in this draft and advises readers to use the information
contained herein with caution.
O'Reilly & Associates grants readers the right to read this material
and to print copies or make electronic copies for their own
use. O'Reilly & Associates does not grant anyone the right to use this
material as part of a commercial product or to modify and distribute
it. When O'Reilly & Associates publishes the final draft of this book
in print form, the content will be made available under an open
content license, but this chapter is not open content.
If you have any comments on the material in this chapter, you should
send them to the authors, Michel Pelletier and Amos Latteier, at
docs@digicool.com.