Z Object Publishing Environment

Search | Download | Documentation | Resources | Members

Search  

 

 Guest

Join Zope.org
Log in


 Zope Exits

Zope Newbies
Technocrat.net
Appwatch.com
CodeCatalog.com

Welcome to Zope.org

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.


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.

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:

          <html>
          <body>
          <h2>Jungle Sales Staff</h2>

          <ul>
            <li>Tarzan</li>
            <li>Cheeta</li>
            <li>Jane</li>
          </ul>
          </body>
          </html>

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:

            http://localhost:8080/Uncles/Rick
            http://localhost:8080/Uncles/Danny 
            http://localhost:8080/Uncles/Louis

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:

        <dtml-var standard_html_header>

        <ul>
          <dtml-in expr="objectValues()">
            <li><dtml-var id></li>
          </dtml-in>
        </ul>

        <dtml-var standard_html_footer>  

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:

          <html>
            <body>
              <img src="logo" width="50"  height="30">

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:

        Animals

          Reptiles

            Snakes

              Pythons

            Lizards

          Mammals

            Primates

            Dogs

            Cats

          Fish

            Gold

            Smelly

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:

        <a href="..">Up to Parent</a><br> 
        <ul>
        <dtml-in expr="objectValues('Folder')">
          <li><a href="&dtml-id;"><dtml-var id></a><br></li>
        </dtml-in>
        </ul>

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:

        <html>
        <body bgcolor="#ffffff">
        <dtml-var navigation>

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:

        <html>
        <body bgcolor="#ffffff">
        <dtml-var default_style_sheet>
        <dtml-var navigation>

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:

        <dtml-var standard_html_header>

        <ul>
        <dtml-in expr="objectValues('File')">
          <li><a href="&dtml-absolute_url;"><dtml-var title_or_id></a></li>
        </dtml-in>
        </ul>

        <dtml-var standard_html_footer>  

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:

        <dtml-var standard_html_header>

        <form action="addEntry" method="POST">
        <input ...>
        </form>

        <dtml-var standard_html_footer>

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.:

        <dtml-var standard_html_header>

        <dtml-call "manage_addDocument(blah, blah)">

        <dtml-with newDocument>
          <dtml-call "setProperty('guestbook_entry')">
          <dtml-call "setProperty('guest_name')">
        </dtml-with>  

        <h1>Thanks for signing our gestbook!</h1>

        <h2>Go <a href="<dtml-var URL1>">Back.</a></h2>

        <dtml-var standard_html_footer>

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:

          <html>
          <body bgcolor="#ffffff">
          <dtml-var default_style_sheet>
          <dtml-var navigation><br>
          <a href="/GuestBook">GuestBook</a> | <a href="/GuestBook/whats_new">What's New!</a><br>

Creat a new DTML Method in the guestbook folder, whats_new:

          <dtml-var standard_html_header>

          <h2><dtml-var title_or_id></h2>
          <ul>
          <dtml-in expr="objectValues('DTML Document')">
            <dtml-if expr="hasProperty('guestbook_entry')">
              <dtml-if expr="bobobase_modification_time < ZopeTime() - 1">
                <li><b>New!</b> - <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>

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:

          <html>
          <body bgcolor="#ffffff">
          <dtml-var default_style_sheet>
          <dtml-var navigation><br>
          <a href="/GuestBook">GuestBook</a> | <a href="/GuestBook?whats_new=1">What's New!</a><br>

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.

 
 
Privacy policy       Printable Page       Feedback about Zope.org      DTML Source