When building a web application with Zope, you construct the application out of objects. By design, different objects handle different parts of your application. Some objects hold your content data, such as word processor documents, spreadsheets and images. Some objects handle your application's logic by accepting input from a web form, or executing a script. Some objects control the way your content is displayed, or presented to your viewer, for example, as a web page, or via email. In general Zope objects take three types of roles:
The word object is a heavily loaded term. Depending on your background, it may mean any number of different things. In this chapter, you can think of a Zope object as an application component that you can control and edit using a web browser.
Zope comes with many built-in objects that help you perform different tasks. You can also install third party Zope objects to expand Zope's capabilities. This chapter explains the most basic objects and how they work. You can create fully functional Zope sites using the few basic objects that are covered in this chapter.
This chapter is loosely structured around the above three categories, Content, Logic, and Presentation. There are other kinds of objects in Zope that don't clearly fit into one of these three roles; those are explained at the end of the chapter.
Folders are the building blocks of Zope. The purpose of a folder is to contain other objects, and to organize objects by separating them into different groups.
Folders can contain all sorts of objects, including other folders, so you can nest folders inside each other to form a tree of folders. This kind of folder within a folder arrangement provides your Zope site with structure. Good structure is very important, as almost all aspects of Zope (from security to behavior to presentation) are influenced by your site's folder structure.
Folder structure should be very familiar to anyone who has worked with files and folders on their computer with a file manager program like Microsoft Windows Explorer or any one of the popular UNIX file managers like xfm, kfm, or the Gnome file manager. The Zope management interface tries to look as much as possible like these popular programs so that you are familiar with how to organize Zope objects just like you would organize files on your computer.
In Chapter 2, "Using Zope" you created objects and moved objects around. In summary, you create objects in folders by choosing the type of the object you are looking for from the pull-down menu at the top of the folder's Contents view. Then you fill out the add form and submit it. A new object is then added to the current folder. You can move objects between folders using the Cut, Copy, Paste, Delete, and Rename buttons.
You can move objects from one Zope system to another using export and import. You can export all types of Zope objects to an export file. This file can then be imported into any other Zope system.
You can think of exporting an object as cloning a piece of your Zope system into a file that you can then move around from machine to machine. You can take this file and graft the clone onto any other Zope server. Imagine you had some 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 export 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 server, and take home with you to work on in your home Zope server. You can create a folder like this in your root folder called "homeWork". Go to the folder that contains your homeWork folder. Select the homeWork folder by checking the checkbox next to it. Then click the Import/Export button. You should now be working in the Import/Export folder view, as shown in Figure 3-1.
Figure 3-1 The Import/Export 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, 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 lets you choose between downloading the export file to your computer or leaving 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 save the file on the same machine on which Zope is running, and you must fetch the file from that location yourself. The export file will be written to Zope's var directory on your server. By default export files have the .zexp file extension.
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, or if you are just trying to move the exported object to another Zope instance on the same computer.
The final export form element is the XML format? checkbox. Checking this box exports the object in the eXtensible Markup Language (XML) format. Leaving this box unchecked exports 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 other tools that can understand Zope's XML format. In general you should leave this box unchecked unless you're curious about what the XML format looks like and 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 server. First, you must copy the export file into Zope's import directory on your server. Now, 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 objects or Retain existing ownership information. Ownership will be discussed more in Chapter 7, "Users and Security". For now, just leave the Take ownership of imported objects option selected.
After you import the file you should have a new object in the Zope folder where you performed the import.
To bring your homework back to school, perform the same export and import procedure. Note that you cannot import an object into a folder that has an existing object with the same id. Therefore, when you bring your homework back to school, you'll need to import it into a folder that doesn't already have a homeWork folder in it. Then, you'll need to delete your old homeWork folder and copy the newly imported one into its place.
Temporary Folders are Zope folders that are used for storing temporary objects. Temporary Folders acts almost exactly like a regular Folder with three significant differences:
By default there is a Temporary Folder in your root folder named temp_folder. You may notice that there is an object entitled, "Session Data Container" within temp_folder. This is an object used by Zope's default sessioning system configuration. See the "Using Sessions" section later in this chapter for more information about sessions.
Temporary folders store their contents in RAM rather than in the Zope database. This makes them appropriate for storing small objects that receive lots of writes, such as session data. However, it's a bad idea use temporary folders to store large objects because your computer can potentially run out of RAM as a result.
In Zope 2.5, a new, powerful type of object was added called Page Templates. Page templates allow you to define dynamic presentation for a web page by writing an HTML template. The HTML in your template is made dynamic by inserting special XML namespace elements to your HTML which define the dynamic behavior for that page.
mock upyour HTML designers do not need to know anything about programming to develop the initial design of a page template.
Create a Folder called Sales in the root folder. Click on the Sales folder and then select Page Template from the add list you learned about in Chapter 2. This process will take you to the add form for a page template. Specify the id "SalesPage" and the title "Template for Sales Staff" and click Add. You have successfully created a page template. However, it's content is standard boilerplate text, so move on to the next step to edit the content.
The easiest way to edit a page template is by clicking on its name or icon in the Zope management interface. When you click on either one of those items, you are taken to the Edit view of the page template which gives you a text-area where you can edit the template. Replace the original content that comes with the page template with the following HTML:
<html> <body> <h1>This is my first page template!</h1> </body> </html>
and click Save. Now you can click on the View tab to view the page template. This particular template does not do anything special or have any dynamic behavior. In later sections in this chapter, we'll add some dynamic behavior. In Chapter 5, you'll use page templates in much greater detail to create dynamic presentation.
Suppose you'd prefer not to edit your HTML templates in a web browser, or you have some existing HTML pages that you'd like to bring into Zope. Zope allows you to upload your existing html files and convert them to page templates.
Select Page Template from the add menu, this will take you to the add form for page templates that we saw earlier.. The last form element on the add form is the Browse button. Click this button. Your browser will then pop up a file selection dialog box. Select the text file on your computer that you want to upload to this template.
Type in an Id for the new Document and click Add. After clicking Add, you will be taken back to the management screen. There you will see your new page template.
Documents hold text. In web applications, you generally use documents to create web pages. You can also use documents to hold text files or snippets of text or HTML code such as sidebars or headers. In addition to containing text, a document allows you to edit the text through the web. Zope has several different types of documents. The most important is DTML Document. DTML stands for Document Template Markup Language.
There are other third-party object types (generally called "Products") available from sources such as Zope.org which will extend your installation to support other types of textual and non-textual content.
Use DTML Documents to create web pages and sections of documents, such as a sidebars that can be shared by web pages. DTML Documents can contain scripting commands in DTML (Zope's tag based scripting language). The mix of HTML and DTML generates dynamic web pages.
DTML Documents are also useful for creating shared content, such as common document structures.
Click on the Sales folder and then select DTML Document from the add list. This process will take you to the add form for a DTML Document. Specify the id "SalesStaff" and the title "The Jungle Sales Staff" and click Add. You have successfully created a DTML Document. However, its content is standard boilerplate text, so move on to the next step to edit the content.
The easiest and quickest way to edit a DTML Document is through the management interface. To select a document, click on its name or icon, which will bring up the form shown in Figure 3-2.
Figure 3-2 Editing a DTML Document
This view shows a text area in which you can edit the content of your document. If you click the Change button you make effective any changes you have made in the text area. You can control the size of the text area with the Taller, Shorter, Wider, and Narrower buttons. You can also upload a new file into the document with a the File text box and the Upload File button.
Delete the default content that is automatically inside the current SalesStaff DTML Document.
Add the following HTML content to the SalesStaff document:
<html> <body> <h2>Jungle Sales Staff</h2> <ul> <li>Tarzan</li> <li>Cheetah</li> <li>Jane</li> </ul> </body> </html>
After you have completed the changes to your document, click the Change button. Zope returns with a message telling you that your changes have taken effect. Now, you can look at the document by clicking the View tab.
Congratulations! You've just used Zope to create an HTML page. You can carry out the creation and editing in one step rather than two by using the Add and Edit button on the add page.
You can edit your HTML online and view it immediately. In fact, you can create entire Zope sites of HTML documents and folders. This process shows just the surface of Zope's benefits, but it provides a good way to familiarize yourself with Zope. You can also write some dynamic content in Zope and let those who are interested purely in design edit their own HTML web pages in this way.
Suppose you'd prefer not to edit your HTML files in a web browser, or you have some existing HTML pages that you'd like to bring into Zope. Zope allows you to upload your existing text files and convert them to DTML Documents.
Select 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 the Browse button. Click this button. Your browser will then pop up a file selection dialog box. Select the text file on your computer that you want to upload to this document.
Type in an Id for the new Document and click Add. After clicking Add, you will be taken back to the management screen. There you will see your new document.
The primary purpose of a DTML document is to hold useful content. This content's primary usage is to be viewed. DTML Documents can be viewed several different ways:
Like all Zope objects, a DTML Document's URL is based on its id. For example, if you have a DTML Document in the root folder called Bob, then its URL would be:
If Bob is in a sub-folder called Uncles then its URL would be:
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 to greater heights. In Zope, URLs are always 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 is key to your site's success.
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 returned 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.
In using Zope you probably have encountered examples of DTML like this:
<dtml-var standard_html_header> <h1>This is some simple HTML</h1> <dtml-var standard_html_footer>
Here we see that one DTML object, standard_html_header is being called by the document that contains this code. In this case, the evaluated contents of the first document are inserted into the contents of this calling document. This is a very fundamental concept in Zope and will be used throughout the book.
The Undo tab lets you undo one transaction at a time, but often it is useful to undo only the change to one object. Remember, a transaction can be a group of actions all taken at the same time. If a document was edited in a transaction that also included moving an object, you may just want to undo the change to the document, but not undo moving the file. To do that, you can go to that object's History View and look at the previous states of the object, as shown in Figure 3-4.
Figure 3-4 The History View
Documents even support the idea of comparing revisions, allowing you to track changes to your objects. For example, DTML Methods and Documents will allow you to select two revisions and compare them to one another. You many want to use this to see what people have done to your object, for example, let's say you had a document that contained a list of all the animals in a Zoo. If one of your co-workers then goes and edits that list and saves it, you can use the history comparison feature to compare the most recent "new" version of the file with the next most recent version.
This comparison is displayed in a popular format called diff. The diff shows you the lines that have been added to the new document (via a plus), which lines have been subtracted from the old document (via a minus), and which lines have been replaced or changed (via an exclamation point).
Zope lets you edit documents directly in your web browser, though this is not the only way documents can be edited in Zope. For simple documents, editing through the web is a handy method. But for large, complex documents, or documents that have special formatting, it's useful to be able to use the editor you are most used to.
DTML Documents can be edited with FTP, WebDAV, and the HTTP PUT protocol. Many HTML and text editors support these protocols for editing documents on remote servers. Each of these protocols has advantages and disadvantages:
Using one of these methods, you can edit your content with a variety of tools. In the next couple sections, we'll show you a couple simple tools that use FTP to edit Zope content.
WS_FTP is a popular FTP client for Windows that you can use to upload documents and files into Zope with the FTP protocol. WS_FTP can be downloaded from the Ipswitch Home Page.
There are other popular Windows FTP clients, and many web browsers like Netscape and Microsoft Internet Explorer come with FTP clients also. This section applies to other FTP clients also.
In Chapter 2, "Using Zope" you determined the URL of your Zope system by looking at the start up log. Finding out how to contact your Zope's FTP server follows a similar process:
------ 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 the machine name and port information so you can connect to Zope via FTP. After typing in the machine name and port of your Zope server, hit the Connect button. WS_FTP will now ask you for a username and password. Enter your management username and password for the Zope management interface.
If you type in your username and password correctly, WS_FTP shows you what your Zope site looks like through FTP. There are folders and documents that correspond exactly to what your root Zope folder looks like through the web, as shown in Figure 3-3.
Figure 3-3 Editing Zope through FTP
Transferring files to and from Zope is a very easy task with WS_FTP. On the left-hand side of the WS_FTP window is a file selection box that represents files on your local machine. The file selection box on the right-hand side of the WS_FTP window represents objects in your Zope system. Transferring 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). WS_FTP has lots of cool features and customizations that you can use to make remote object management with Zope very easy.
Emacs is a very popular text editor. In fact, 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.
Emacs will let you treat any remote FTP system like any other local filesystem, making remote management of Zope content an easy process. Therefore, you need not leave Emacs in order to use Zope.
Emacs provides a richer set of text editing capabilities than most web browser text areas. Emacs can be used to directly edit documents and manipulate objects through FTP, therefore Emacs is a nice Zope development environment.
By default when you start up Zope, Zope runs an FTP server just as it runs an HTTP server. You can specify when you start Zope which port the FTP server should listen on, but by default this port is 8021.
To log into Zope, run Emacs. The file you visit to open an FTP connection depends on which text editor you are running: XEmacs or Emacs:
This will open a connection to the / folder of the FTP server running on server and listening on port port.
The literal space is inserted by holding down the Control key and the Q key, and then pressing the space "C-Q ".
For the typical Zope installation with XEmacs, the filename to open up an FTP session with Zope is */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. Editing with Emacs is very useful, but for the most part, Emacs is a very complex program that is not very accessible to most people. Most Macintosh users, for example, would be very unfamiliar with a tool like Emacs. There are a number of "easier" editors that can be used that also use FTP and WebDAV. WebDAV is, in fact, designed to be used by tools like Adobe GoLive and Macromedia Dreamweaver.
WebDAV is a newer Internet protocol compared to HTTP or FTP, so there are fewer clients that support it. There is, however, a lot of momentum behind the WebDAV movement and more clients are being developed all the time. For more information on what programs support the WebDAV protocol, see the WebDAV homepage.
WebDAV is an extension to the HTTP protocol that provides rich features for many users concurrently authoring and editing content on web sites. WebDAV offers features like locking, revision control, and tagging documents or objects with properties. Because WebDAV's goals of through the web editing match some of the goals of Zope, Zope has supported the WebDAV protocol for quite a while.
The WebDAV protocol is evolving quickly, and new features are being added all the time. You can use any WebDAV client to edit your DTML Documents by simply pointing the client at your document's URL and editing it. For most clients, however, this will cause them to try to edit the result of rendering the document, not the source. For documents that use Zope's DTML template language to render dynamic content, this can be a problem.
Until clients catch up to the latest WebDAV standard and understand
the difference between the source of a document and its result, Zope
offers a special HTTP server you can enable with the
command line option. This server listens on a different port than
your normal HTTP server and returns different, special source content
for WebDAV requests that come in on that port. This is an advanced
feature and is explained more in the Documentation
Section of Zope.org.
Zope Files contain raw data, just as the files on your computer do. 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.
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. Files are also good for holding textual content that doesn't need DTML scripting.
Every File object has a particular content type which is a standard Internet MIME designation for file type. When you upload a file into Zope, Zope tries to guess the content type from the name of the file, but Zope doesn't always guess correctly.
Like DTML Documents and Methods, Files allow you to upload a file from your computer when you create a new object. Click the Browse button to choose a file from your local computer when creating a new Zope File. Try choosing a file such as a Word file (.doc) or a Portable Document Format (.pdf) file. Note, when uploading a file with your browser, you may have to indicate the file type you're looking for in your browser's upload dialog box. 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, click on the new File and look at its Edit view. Here you will see that Zope has guessed the content type as shown in Figure 3-5.
Figure 3-5 File content-type property
If you add a Word document, the content type is application/msword. If you add a PDF file, the content type is application/pdf. If Zope does not recognize the file type, it chooses the default, generic content type of application/octet-stream.
You can change the contents of an existing File by going to the Upload view. Here you can replace the contents of the File with a new file. If you don't fill in an id and title in this form and you upload a file, Zope will use the filename as the id and the title of the object.
If your File holds text and is less than 64K, then Zope lets you edit it in the management interface. A text file is one that has a content-type that starts with text/, such as text/html, or text/plain. You may sometimes find it convenient to edit text files in the management interface. In any case, you can always edit files locally and then upload them to Zope.
You can view a file by going to the View tab from the management interface. You can also view a File by visiting its URL. In fact the View tab is just a way to get to a File's URL from the Zope management interface. 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. Depending on the type of the file, your web browser may display the file or download it.
Images display graphics such as GIF, JPEG, and PNG files. In Zope, Images are similar to File objects, but include extra behavior for managing graphic content.
Image objects have the same management interface as file objects. Everything in the previous section about using file objects also applies to images. However, Image objects show you a preview of the image when you upload them.
The most common use for Images in Zope is putting pictures in web pages. To put a picture into a web page, you need to use the HTML IMG tag. Suppose you have an Image object in your root folder called logo that contains an image of your organizations logo.
Using this Image in your HTML is a straight forward process: you can reference it with an IMG tag as you'd do to include any type of image in a web page:
<dtml-var standard_html_header> <img src="logo"> <h1>Welcome!</h1> <dtml-var standard_html_footer>
In this example, you reference the logo image by creating an HTML IMG tag, but usually 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 an IMG tag for itself.
Now, we want this logo to be seen on every page up in the upper left-hand corner, so put a reference to it in the 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 Zope creates, you can see
var DTML code was turned into an HTML IMG tag
<html> <body> <img src="logo" width="50" height="30">
Using the DTML var tag to draw Images makes things simple, because Zope automatically figures out the height and width attributes of the IMG tag for you. If you don't like the way Zope constructs an IMG tag, it can be customized. See Appendix B for more information on the Image object and how it can control the IMG tag.
There are a number third party Zope object types (generally called "Products") for storing and viewing image content available from the visual section of Zope.org.
Images can be viewed directly by going to their URL in your web browser. For example, let's say you want to view your company logo directly. The logo exists as an image object in your root folder. It is called logo, you can easily view it by going directly to its URL http://localhost:8080/logo.
Since Zope Images work just like images stored in a normal web server, you can access your Zope images from other web servers. Suppose you have a Zope Image whose URL is http://imageserver:8080/Birds/Parakeet.jpg. You can include this Image in any web page served from any web server using the Image's absolute URL in your web page:
<html> <h1>Remote Image</h1> <img src="http://imageserver:8080/Birds/Parakeet.jpg"> </html>
This example shows how you can use Zope data from outside Zope using standard Internet protocols. Later in Chapter 10, "Advanced Zope Scripting" you'll see how most Zope objects can provide services to the outside world.
Properties are ways of associating information with objects in Zope. Many Zope objects, including folders and documents, support properties. Properties can label an object in order to identify its contents (many Zope content objects have a content type property). Another use for properties is to provide meta-data for an object such as its author, title, status, etc.
Properties can be more complex than strings; they can also be numbers, lists, or other data structures. All properties are managed via the Properties view. Click on an object's Properties tab and you will be taken to the properties management view, as seen in Figure 3-6.
Figure 3-6: The Properties Management View
A property consists of a name, a value and a type. A property's type defines what kind of value or values it can have.
In Figure 3-6 you can see that the folder has three properties, title, Author, KeyWords. The title and Author property are string properties, while the KeyWords property has a type of tokens. A tokens property is like a sequence of words.
Zope supports a number of property types. Each type is suited to a specific task. This list gives a brief overview of the kinds of properties you can create from the management interface:
Properties are very useful tools for tagging your Zope objects with little bits of data or information. In conjunction with methods and scripts, properties make extending simple objects like Folders a very powerful technique.
In traditional programming lingo, a script is a short piece of code written in a programming language. As of version 2.3, Zope now comes with two kinds of script objects: one that lets you write scripts in Python and one that lets you write scripts in Perl.
Both Python and Perl are very popular and powerful programming languages. Both Python and Perl share many similar feature: both offer powerful, rapid development, simple syntax, many add-on libraries, strong community following, and copious amounts of free, online documentation. Both languages are also open source.
Because scripts are so powerful and flexible, their possible uses are endless. Scripts are primarily used to write what is called business logic. Business logic is different than presentation logic. Presentation logic is usually written in a presentation language, like DTML, and its purpose is to display information to a user. Business logic is usually written in a scripting language, and its purpose is to manipulate information that comes from content sources (like documents or databases) or manipulate other objects. Often, presentation logic is based on top of business logic.
A simple example of using scripts is building an online web form to help your users calculate the amount of compound interest on their debts. This kind of calculation involves the following procedure:
For this example, you will need two page templates named interestRateForm and interestRateDisplay to collect the information from the user and display it, respectively. You will also need a Python-based script called calculateCompoundingInterest that will do the actual calculation. The first step is to create a web form in interestRateForm that collects "principal", "interest_rate", "periods" and "years" from your users. Here's an example interestRateForm page templates:
<html> <body> <form action="interestRateDisplay" method="POST"> <p>Please enter the following information:</p> Your current balance (or debt): <input name="principal:float"><br> Your annual interest rate: <input name="interest_rate:float"><br> Number of periods in a year: <input name="periods:int"><br> Number of years: <input name="years:int"><br> <input type="submit" value=" Calculate "><br> </form> </body> </html>
This form collects information and calls the interestRateDisplay template. Now, create a Python-based script called calculateCompoundingInterest that accepts four parameters, "principal", "interest_rate", "periods" and "years" with the following python code:
## Script (Python) "calculateCompoundInterest" ##parameters=principal, interest_rate, periods, years ## """ Calculate compounding interest. """ i = interest_rate / periods n = periods * years return ((1 + i) ** n) * principal
Enter the parameters into the Parameters List field, and the code in the body text area. The comments shown at the beginning of the code are not necessary when editing through the web. (However these comments are useful for editing scripts via FTP.)
This will return the balance or debt compounded over the course of "years". Next, create a interestRateDisplay page template that calls calculateCompoundingInterest and returns the result:
<html> <body> <p>Your total balance (or debt) including compounded interest over <span tal:content="years">2</span> years is:</p> <p><b>$<span tal:content="python: here.calculateCompoundingInterest(principal, interest_rate, periods, years)" >1.00</span></b></p> </body> </html>
First view the interestRateForm page template. Now, type in some information about your balance or debt and click Calculate. This will cause interestRateForm to submit the collect information to interestRateDisplay, which calls the Python-based script calculateCompoundingInterest. The display method uses the value returned by the script in the resulting display.
As we said earlier, the possibilities for using scripts is almost endless. This example, however, gives you a good idea of the most common pattern for presentation objects to collect and display information, and using business logic objects to make calculations.
Methods are objects in Zope that hold special executable content. The name "Method" is actually a bit of a misnomer, and its use in Zope is slowly being phased out for more common terms like Script and Template.
Zope comes with two kinds of methods, DTML Methods and SQL Methods. DTML Methods are used to define presentation templates that you can apply to content objects like DTML Documents and Files. A very common and popular way to use DTML Methods is to define presentation layout separate from your content.
SQL Methods are used to contain database queries that you can reuse throughout your web application. SQL Methods are explained in Chapter 12, "Relational Database Connectivity", where an example of creating a web application using a relational database is given.
All the various objects in Zope can be manipulated by calling
methods on those objects. For example, Folder objects have an
objectValues method that returns the objects contained by the
folder. DTML Methods can be used to write simple scripts that call
these Zope API methods. These methods are documented in the Help
System, under API Documentation.
Before Zope 2.3, DTML Methods were the only way to write scripts in Zope with your web browser. While DTML is useful for very simple scripts and for presenting information with templates, this approach had a number of limitations because DTML isn't as flexible as other programming languages.
Zope 2.3 introduces two new kinds of Script objects based on two very popular programming languages, Python (which Zope is written in) and Perl. You should use Python and Perl-based scripts to write more complex scripts instead of a DTML Method. While browsing through past Zope documentation, mail list archives, and other resources on "Zope.org"http://www.zope.org, you may find a lot of references to very complex DTML scripts. These pre-date Python and Perl-based scripts. In general, complex scripts should be written in either Python or Perl. Python and Perl-based scripts are described later in this chapter, and many examples of their use is given in Chapter 10, "Advanced Zope Scripting".
A simple example of using DTML Methods is to create a DTML Method in the root folder called objectList:
<dtml-var standard_html_header> <ul> <dtml-in objectValues> <li><dtml-var getId></li> </dtml-in> </ul> <dtml-var standard_html_footer>
When you view this method, it calls the objectValues method on the root folder and this shows you a simple HTML list of all the objects in the root folder, as shown in Figure 3-7.
Figure 3-7 Results of the objectList DTML Method
All folders implement the objectValues method. The objectValues method is part of an interface that all folders implement called ObjectManager.
In addition to calling API methods on objects, DTML Methods can also be used in a certain way to extend any Zope object. This will be explained in more detail in the next chapter. In effect, this allows you to extend the Zope API by simply creating DTML Methods.
You just saw the objectList method, which resides in the root folder, and makes 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 in or below the root folder. This method extends the Zope API for these objects since it provides them with another callable method.
To demonstrate, let's create a subfolder called Primates and add three documents, Monkeys, Apes, Humans. You can call the objectList method on the Primates folder by visiting the URL Primates/objectList. You can see the effect of calling the objectList method on the Primates folder differs from the effect of calling it on the root folder. 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 4, "Dynamic Content with DTML".
DTML Methods mainly serve as presentation templates. DTML Methods can act as templates tying reusable bits of content together into dynamic web pages. The template features of DTML Methods will be discussed in further detail in the next chapter.
DTML Methods have the 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 are identical for DTML Methods.
A source of frequent confusion for Zope beginners is the question of when to use a DTML Document versus when to use a DTML Method. On the surface, these two options 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 general rule is: if your content is mostly document-like and you want to present it on your site, then it should go into a DTML Document.
DTML Methods are meant to manipulate and display other objects. DTML Methods don't usually hold a lot of content, unless the content is meant to change or manipulate other content.
Don't worry if you're still unclear on the differences between DTML Document and Methods. Even the most experienced Zope programmers need to think a little before deciding which type of object to use. In Chapter 8, "Variables and Advanced DTML", you'll learn about the technical differences between DTML Documents and DTML Methods (they look up variables differently since they have different "client" objects). Here are some general rules to help you decide between DTML Documents and Methods:
As you've seen DTML Methods are a useful tool for presentation and quick scripting, but eventually you're going to want to power of a fully expressive programming language, and that's where Scripts come in.
Sessions allow you keep track of site visitors. Web browsers use a protocol named HTTP to exchange data with a server such as Zope. HTTP is does not provide a way for the server to keep track of a user's requests; each request is considered completely independent.
You can use sessions to keep track of anonymous users as well as those who have Zope login accounts.
Data associated with a session is called "session data". Session data is valid only for the duration of one site visit as determined by a configurable inactivity timeout value. Session data is used to keep track of information about a user's visit such as the items that a user has put into a "shopping cart", or which pages a user has seen on his trip to your site.
It is important to realize that keeping sensitive data in a session data object is potentially insecure unless the connection between browsers and Zope is encrypted in some way. Don't store sensitive information such as phone numbers, addresses, account numbers, credit card numbers or any other personal information about your site visitors unless you've secured the connection between Zope and site visitors via SSL.
Zope versions after 2.5 come with a default sessioning environment configured "out of the box", so there's no need to change these objects unless you're curious or want to change how sessions are configured. For information on changing sessioning configuration, use the Zope help system.
Zope uses several different types of objects to manage session data, and brief explanations of their purpose follow.
/temp_folder/session_data. The session data objects in the default
session_dataTransient Object container are lost each time Zope is restarted.
You will typically access session data through the
attribute of the REQUEST object.
Here's an example of how to work with a session using a Python-based Script:
## Script (Python) "lastView" secs_per_day=24*60*60 session=context.REQUEST.SESSION if session.has_key('last view'): # The script has been viewed before, since the 'last view' # has been previously set in the session. then=session['last view'] now=context.ZopeTime() session['last view']=now # reset last view to now return 'Seconds since last view %.2f' % ((now - then) * secs_per_day) # The script hasn't been viewed before, since there's no 'last # view' in the session data. session['last view']=context.ZopeTime() return 'This is your first view'
View this script, and then reload it a couple of times. It keeps track of when you last viewed the script and calculates how long it has been since you last viewed it. Notice that if you quit your browser and come back to the script it forgets you. However, if you simply visit some other pages and then return, it still remembers the last time you viewed it.
This example shows the basic features of working with session data: session data objects act like Python dictionaries. You will almost always use session data that consists of normal Python lists, dictionaries, strings, and numbers. The only tricky thing about sessions is that when working with mutable session data (for example dictionaries or lists) you need to save the session data by reassigning it. Here's an example:
## Script (Python) "sessionExample" session=context.REQUEST.SESSION # l is a list l=session['myList'] l.append('spam') # If you quit here, your changes to the list won't # be saved. You need to save the session data by # reassigning it to the session. session['myList']=l
For more information about persistence and mutable data, see the Zope Developer's Guide.
You can use sessions in Page Templates and DTML Documents, too. For example, here's a template snippet that displays the users favorite color (as stored in a session):
Here's how to do the same thing in DTML:
<dtml-with SESSION mapping> <p><dtml-var favorite_color></p> </dtml-with>
Sessions have a plethora of additional configuration parameters and usage patterns. For further information about the session application programming interface, see the Zope help system. For an additional example of using sessions, see the "shopping cart" example that comes with Zope 2.5 and above (in the Examples folder).
Version objects help coordinate the work of many people on the same set of objects. While you are editing a document, someone else can be editing another document at the same time. In a large Zope site hundreds or even thousands of people can be using Zope simultaneously. For the most part this works well, but problems can occur. For example, two people might edit the same document at the same time. When the first person finishes their changes they are saved in Zope. When the second person finishes their changes they over write the first person's changes. You can always work around this problem using Undo and History, but it can still be a problem. To solve this problem, Zope has Version objects.
Another problem that you may encounter is that you may wish to make some changes, but you may not want to make them public until you are done. For example, suppose you want to change the menu structure of your site. You don't want to work on these changes while folks are using your site because it may break the navigation system temporarily while you're working.
Versions are a way of making private changes in Zope. You can make changes to many different documents without other people seeing them. When you decide that you are done you can choose to make your changes public, or discard them. You can work in a Version for as long as you wish. For example it may take you a week to put the finishing touches on your new menu system. Once you're done you can make all your changes live at once by committing the version.
Create a Version by choosing Version from the product add list. You should be taken to an add form. Give your Version an id of MyChanges and click the Add button. Now you have created a version, but you are not yet using it. To use your version click on it. You should be taken to the Join/Leave view of your version as shown in Figure 3-8.
Figure 3-8 Joining a Version
The Version is telling you that you are not currently using it. Click on the Start Working in MyChanges button. Now Zope should tell you that you are working in a version. Now return to the root folder. Notice that everywhere you go you see a small message at the top of the screen that says You are currently working in version /MyChanges. This message lets you know that any changes you make at this point will not be public, but will be stored in your version. For example, create a new DTML Document named new. Notice how it has a small red diamond after its id. Now edit your standard_html_header method. Add a line to it like so:
<HTML> <HEAD> <TITLE><dtml-var title_or_id></TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF"> <H1>Changed in a Version</H1>
Any object that you create or edit while working in a version will be marked with a red diamond. Now return to your version and click the Quit working in MyChanges button. Now try to return to the new document. Notice that the document you created while in your version has now disappeared. Any other changes that you made in the version are also gone. Notice how your standard_html_header method now has a small red diamond and a lock symbol after it. This indicates that this object has been changed in a version. Changing an object in a version locks it, so no one else can change it until you commit or discard the changes you made in your version. Locking ensures that your version changes don't overwrite changes that other people make while you're working in a version. So for example if you want to make sure that only you are working on an object at a given time you can change it in a version. In addition to protecting you from unexpected changes, locking also makes things inconvenient if you want to edit something that is locked by someone else. It's a good idea to limit your use of versions to avoid locking other people out of making changes to objects.
Now return to your version by clicking on it and then clicking the Start working in MyChanges button. Notice how everything returns to the way it was when you left the Version. At this point let's make your changes permanent. Go to the Save/Discard view as shown in Figure 3-9.
Figure 3-9 Committing Version changes.
Enter a comment like This is a test into the comment field and click the Save button. Your changes are now public, and all objects that you changed in your Version are now unlocked. Notice that you are still working in your Version. Go to the Join/Leave view and click the Quit Working in MyChanges button. Now verify that the document you created in your version is visible. Your change to the standard_html_header should also be visible. Like anything else in Zope you can choose to undo these changes if you want. Go to the Undo view. Notice that instead of many transactions one for each change, you only have one transaction for all the changes you made in your version. If you undo the transaction, all the changes you made in the version will be undone.
Versions are a powerful tool for group collaboration. You don't have to run a live server and a test server since versions let you make experiments, evaluate them and then make them public when you decide that all is well. You are not limited to working in a version alone. Many people can work in the same version. This way you can collaborate on version's changes together, while keeping the changes hidden from the general public.
Versions don't work well with ZCatalog. This is because versions lock objects when they are modified in a version, preventing changes outside the version. This works well when changes are isolated.
ZCatalog has a way of connecting changes made to disparate objects. This is because cataloging an object must, by necessity change the catalog. Objects that automatically catalog themselves when they are changed propigate their changes to the catalog. If such an object is changed in a version, then the catalog is changed in the version too, thus locking the catalog. This property makes the catalog and versions get along poorly. As a rule, versions should not be used in applications that use the catalog.
A cache is a temporary place to store information that you
access frequently. The reason for using a cache is speed. Any
kind of dynamic content, like a DTML page or a Python Script, must
be evaluated each time it is called. For simple pages or quick
scripts, this is usually not a problem. For very complex DTML
pages or scripts that do a lot of computation or call remote
servers, accessing that page or script could take more than a
trivial amount of time. Both DTML and Python can get this
complex, especially if you use lots of looping (such as the
tag or the Python
for loop) or if you call lots of scripts, that
in turn call lots of scripts, and so on. Computations that take a
lot of time are said to be expensive.
A cache can add a lot of speed to your site by calling an expensive page or script once and storing the result of that call so that it can be reused. The very first person to call that page will get the usual slow response time, but then once the value of the computation is stored in the cache, all subsequent users to call that page will see a very quick response time because they are getting the cached copy of the result and not actually going through the same expensive computation the first user went through.
To give you an idea of how caches can improve your site speed, imagine that you are creating www.zopezoo.org, and that the very first page of your site is very complex. Let's suppose this page has complex headers, footers, queries several different database tables, and calls several special scripts that parse the results of the database queries in complex ways. Every time a user comes to www.zopezoo.org, Zope must render this very complex page. For the purposes of demonstration, let's suppose this complex page takes one-half of a second, or 500 milliseconds, to compute.
Given that it takes a half of a second to render this fictional complex main page, your machine can only really serve 120 hits per minute. In reality, this number would probably be even lower than that, because Zope has to do other things in addition to just serving up this main page. Now, imagine that you set this page up to be cached. Since none of the expensive computation needs to be done to show the cached copy of the page, many more users could see the main page. If it takes, for example, 10 milliseconds to show a cached page, then this page is being served 50 times faster to your web site visitors. The actual performance of the cache and Zope depends a lot on your computer and your application, but this example gives you an idea of how caching can speed up your web site quite a bit. There are some disadvantages to caching however:
Zope allows you to get around these problems by setting up a cache policy. The cache policy allows you to control how content gets cached. Cache policies are controlled by Cache Manager objects.
Cache managers can be added just like any other Zope object. Currently Zope comes with two kinds of cache managers:
For the purposes of this example, create a RAM Cache Manager in the root folder called CacheManager. This is going to be the cache manager object for your whole site.
Now, you can click on CacheManager and see its configuration screen. There are a number of elements on this screen:
For now, leave all of these entries as is, they are good, reasonable defaults. That's all there is to setting up a cache manager!
There are a couple more views on a cache manager that you may find useful. The first is the Statistics view. This view shows you the number of cache "hits" and "misses" to tell you how effective your caching is.
There is also an Associate view that allows you to associate a specific type or types of Zope objects with a particular cache manager. For example, you may only want your cache manager to cache DTML Documents. You can change these settings on the Associate view.
At this point, nothing is cached yet, you have just created a cache manager. The next section explains how you can cache the contents of actual documents.
Caching a document is very easy. First, before you can cache a document you must have a cache manager like the one you created in the previous section.
To cache a document, create a new DTML Document object in the root folder called Weather. This object will contain some weather information. For example, let's say it contains:
<dtml-var standard_html_header> <p>Yesterday it rained.</p> <dtml-var standard_html_footer>
Now, click on the Weather DTML Document and click on its Cache view. This view lets you associate this document with a cache manager. If you pull down the select box at the top of the view, you'll see the cache manager you created in the previous section, CacheManager. Select this as the cache manager for Weather.
Now, whenever anyone visits the Weather document, they will get the cached copy instead. For a document as trivial as our Weather example, this is not much of a benefit. But imagine for a moment that Weather contained some database queries. For example:
<dtml-var standard_html_header> <p>Yesterday's weather was <dtml-var yesterdayQuery> </p> <p>The current temperature is <dtml-var currentTempQuery></p> <dtml-var standard_html_footer>
Let's suppose that yesterdayQuery and currentTempQuery are SQL Methods that query a database for yesterdays forecast and the current temperature, respectively (for more information on SQL Methods, see Chapter 12, "Relational Database Connectivity"). Let's also suppose that the information in the database only changes once every hour.
Now, without caching, the Weather document would query the database every time it was viewed. If the Weather document was viewed hundreds of times in an hour, then all of those hundreds of queries would always contain the same information.
If you specify that the document should be cached, however, then the document will only make the query when the cache expires. The default cache time is 300 seconds (5 minutes), so setting this document up to be cached will save you 91% of your database queries by doing them only one twelfth as often. There is a trade-off with this method, there is a chance that the data may be five minutes out of date, but this is usually an acceptable compromise.
For more information about caching and using the more advanced options of caching, see the Zope Administrator's Guide.
Zope comes with three objects that help you do virtual hosting, SiteRoot, Set Access Rule, and Virtual Host Monster. Virtual hosting is a way to serve many web sites with one Zope server. Virtual hosting is an advanced administration function, that is beyond the scope of this book. See the Zope Administrator's Guide for more information on virtual hosting.
Zope comes with an object that is used to send outbound e-mail,
usually in conjunction with the DTML
sendmail tag, described more
in Chapter 8, "Variables and Advanced DTML".
Mailhosts can be used from either Python or DTML to send an email
message over the Internet. They are useful as
gateways out to
the world. Each mailhost object is associated with one mail
server, for example, you can associate a mailhost object with
yourmail.yourdomain.com, which would be your outbound SMTP mail
server. Once you associate a server with a mailhost object, the
mailhost object will always use that server to send mail.
To create a mailhost object select MailHost from the add list. You can see that the default id is "MailHost" and the default SMTP server and port are "localhost" and "25". make sure that either your localhost machine is running a mail server, or change "localhost" to be the name of your outgoing SMTP server.
Now you can use the new MailHost object from a DTML
tag. This is explained in more detail in Chapter 8, "Variables
and Advanced DTML". The API for MailHost objects also allows you
to send mail from Python scripts. For more information, see the
online help system.