Using Basic Zope Objects

When building a web application with Zope, you construct the application out of objects. The most fundamental Zope objects are explained in this chapter.

Basic Zope Objects

Zope ships with objects that help you perform different tasks. 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, basic Zope objects take on one of three types of roles:

Content
Zope objects such as documents, images and files hold different kinds of textual and binary data. In addition to objects in Zope containing content, Zope can work with content stored externally, for example, in a relational database.
Presentation
You can control the look and feel of your site with Zope objects that act as web page "templates". Zope comes with two facilities to help you manage presentation: DTML (which also handles "logic"), and Zope Page Templates (ZPT). The difference between DTML and ZPT is that DTML allows you to mix presentation and logic, while ZPT does not.
Logic
Zope has facilities for scripting business logic. Zope allows you to script behavior using three facilities: Document Template Markup Language (DTML), Python, and Perl (Perl is only available as an add-on). "Logic" is any kind of programming that does not involve presentation, but rather involves carrying out tasks like changing objects, sending messages, testing conditions and responding to events.

The lines between these object categories can become slightly fuzzy. For example, some aspects of DTML fit into each of the three categories. But it's mostly for presentation so we stick it in there. Zope also has other kinds of objects that fit into none of these categories. These are explored further in the chapter entitled Zope Services. You may also install "third party" Zope objects to expand Zope's capabilities. These are typically called "Products". You can browse a list of available Zope Products at Zope.org.

Content Objects: Folders, Files, and Images

Folders

You've already met one of the fundamental Zope objects: the Folder. Folders are the building blocks of Zope. The purpose of a folder is simple: a Folder's only job in life is to contain other objects.

Folders can contain any other kind of Zope object, including other folders. 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 Zope security and presentation is 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 using 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.

Files

Zope Files contain raw data, just as the files on your computer do. Software, audio, video and documents are typically transported around the Internet and the world as files. A Zope File object is an analogue to these kinds of files. You can use Files to hold any kind of information that Zope doesn't specifically support, such as Flash files, Java 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 if the content doesn't necessarily need to be edited through the web.

Every File object has a particular content type which is a standard Internet MIME designation for types of content. Examples of content types are "text/plain" (plain text content), "text/html" (html text content), and "application/pdf" (an Adobe Portable Document Format file). When you upload a file into Zope, Zope tries to guess the content type from the name of the file.

Creating and Editing Files

To create a File object in your Zope instance, visit the root folder and select File from Zope's Add list. Before filling out the "id" or "title" of the File object, click the Browse button from the resulting "Add File" screen. This should cause your browser to display a dialog box allowing you to choose a "real" file from your local computer which will be uploaded to Zope when the "Add" button on the "Add File" form is selected. Try choosing a file on your local computer such as a Word file (.doc) or a Portable Document Format (.pdf) file.

Adding a PDF File Object

Figure 4-1 Adding a PDF File Object

 

Zope attempts to use the filename of the file you choose to upload as the File object's id and title, thus you don't need to supply an id or title in the "Add File" form unless you want the File object to be named differently than the filename of the file on your local computer. 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 you add the File, a File object with the name of the file on your local computer will appear in the Workspace pane. Look at its Edit view. Here you will see that Zope has guessed the content type as shown in the figure below.

Editing an Uploaded PDF File Object

Figure 4-2 Editing an Uploaded PDF File Object

 

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. Zope doesn't always guess correctly, so the ability to change the content type of a File object is provided in the editing interface. To change the content type of a File object, type the new content type into the Content Type form field and click the Save Changes button.

You can specify a precondition for a file. A precondition is the name of an executable Zope object (such as a DTML Method, a Script (Python), or an external method) which is executed before the File is viewed or downloaded. If the precondition raises an exception (an error), the file cannot be viewed. This is a seldom-used feature of Files.

You can change the contents of an existing File object by selecting a new file from your local filesystem in the File Data form element, clicking Upload when the file has been selected.

Editing File Contents

If your File holds only text and is smaller than 64 kilobytes, Zope will allow you to edit its contents in a textarea within the Edit view of the management interface. A text file is one that has a content-type that starts with text/, such as text/html, or text/plain.

Viewing Files

You can view a file in the Workspace frame by clicking the View tab from a File's management screen.

Viewing an Uploaded PDF File Object

Figure 4-3 Viewing an Uploaded PDF File Object

 

You can also view a File by visiting its Zope URL. For example, if you have a file in your Zope root folder called Reader.pdf then you can view that file in your web browser by going to the URL http://localhost:8080/Reader.pdf. Depending on the type of the file and your web browser's configuration, your web browser may choose to display the file or download it.

Images

Image objects contain the data from image files such as GIF, JPEG, and PNG files. In Zope, Images are very 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.

Presentation Objects: Zope Page Templates and DTML Objects

Zope encourages you to keep your presentation and logic separate by providing different objects that are intended to be used expressly for "presentation". "Presentation" is defined as the task of dynamically defining layout of web pages and other user-visible data. Presentation objects typically render HTML (and sometimes XML or WML).

Zope has two "presentation" facilities: Zope Page Templates (ZPT) and Document Template Markup Language (DTML). ZPT and DTML are similar to one another but they have slight differences in scope and audience, which are explained in a succeeding section.

Zope Page Templates are objects which allow you to define dynamic presentation for a web page. The HTML in your template is made dynamic by inserting special XML namespace elements into your HTML which define the dynamic behavior for that page.

Document Template Markup Language objects are objects which also allow you to define presentation for a web page. The HTML in your template is made dynamic by inserting special "tags" (directives surrounded by angle brackets, typically) into your HTML with define the dynamic behavior for that page.

Both ZPT and DTML are "server-side" scripting languages, like SSI, PHP, embperl, or JSP. This means that DTML and ZPT commands are executed by Zope on the server, and the result of that execution is sent to your web browser. By contrast, client-side scripting languages like Javascript are not processed by the server, but are rather sent to and executed by your web browser.

ZPT vs. DTML: Same Purpose, Different Audiences

There is a major problem with many languages designed for the purpose of creating dynamic HTML content: they don't allow for "separation of presentation and logic" very well. For example, "tag-based" scripting languages like DTML, SSI, PHP, and JSP encourage programmers to embed special tags into HTML that are, at best, mysterious to graphics designers who "just want to make the page look good" and don't know (or want to know!) a lot about creating an application around the HTML which they generate. Worse, these tags can sometimes cause the HTML on which the designer has been working to become "invalid" HTML, unrecognizable by any of his or her tools.

Typically when using these kinds of technologies, an HTML designer will "mock up" a page in a tool like Macromedia Dreamweaver or Adobe GoLive. He will then hand it off to a web programmer who will decorate the page with special tags to insert dynamic content. However, using tag-based scripting languages, this is a "one way" function. If the presentation ever needs to change, the programmer cannot just hand back the page that has been "decorated" with the special tags, because these tags will often be ignored or stripped out by the designer's tools. One of several things needs to happen at this point to enact the presentation changes: 1) the designer mocks up a new page and the programmer re-embeds the dynamic tags "from scratch" or 2) the designer hand-edits the HTML, working around the dynamic tags, or 3) the programmer does the presentation himself. Clearly, none of these options are desirable situation, because neither the programmer nor the designer are doing the things that they are best at in the most efficient way.

Zope's original dynamic presentation language was DTML. It soon became apparent that DTML was great at allowing programmers to quickly generate dynamic web pages, but many times failed at allowing programmers to work effectively together with nontechnical graphics designers. Thus, ZPT was born. ZPT is an "attribute-based" presentation language that tries to allow for the "round-trippping" of templates between programmers and nontechnical designers.

Both ZPT and DTML are fully supported in Zope, for now and in the future. Because ZPT and DTML have an overlapping scope, many people are confused about whether to choose one or the other for a given task. A set of "rules of thumb" are appropriate here:

  • ZPT is the "tool of choice" if you have a mixed team of programmers and nontechnical designers. Design tools like Macromedia Dreamweaver do not "stomp on" ZPT embedded in a page template, while these tools do "stomp on" DTML tags embedded in an HTML page. Additionally, any given ZPT page template is typically viewable in a browser with "default" (static) content even if it has commands embedded in it, which makes it easier for both programmers and designers to preview their work "on the fly". Dynamic DTML content, on the other hand may not be "previewable" in any meaningful way until it is rendered.
  • Use DTML when you need to generate non-XML, non-HTML, or non-XHTML-compliant HTML text. ZPT requires that you create pages that are XHTML and/or XML-compliant. ZPT cannot add dynamicism to CSS style sheets, SQL statements, or other non-XML-ish text. DTML excels at it.
  • DTML may be easier for some programmers to write because it provides greater control over "conditionals" ("if this, do this, else, do that") than does ZPT. In this respect, it more closely resembles languages such as PHP and ASP-based scripting languages than does ZPT, so it's typically a good "starting place" for programmers coming from these kinds of technologies.
  • DTML code can become "logic-heavy" because it does not enforce the "separation of presentation from logic" as strictly as does ZPT. Embedding too much logic in presentation is almost always a bad thing, but is particularly bad when you are working on a "mixed" team of programmers and designers. If you're a "separation of presentation from logic" purist, you will almost certainly prefer ZPT.

 

Zope Page Templates

Zope Page Templates (ZPTs) are typically used to create dynamic HTML pages.

Creating A Page Template

Create a Folder with the id Sales in the root folder, and give it any title you like. Enter the Sales folder by clicking on it, then select Page Template from the Add list. The add form for a page template will be displayed. Specify the id "SalesPage" and click Add. You have successfully created a page template. Its content is standard "boilerplate" text at this point.

Editing A Page Template

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 textarea where you can edit the template. Click on the "SalesPage" template. You will see something like:

Default Page Template Content

Figure 4-4 Default Page Template Content

 

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>

 

Then click Save Changes at the bottom of the edit form.

Uploading A Page Template

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

Create a text file on your local computer named upload_pt.html. Populate it with the following content:

        <html>          <body>            <h1>This is my second page template!</h1>          </body>        </html>

 

While visiting the Sales folder, select Page Template from the add menu, which will cause the page template add form to be displayed. 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 upload_pt.html file, type in an id of "upload_pt" for the new Page Template and click Add and Edit. After clicking Add and Edit, you will be taken back to the Edit form of your uploaded page template.

Viewing A Page Template

You can view a Page Template in the Workspace frame by clicking the Test tab from the template's management screen. Click the Test tab of the SalesPage template, and you will see something like the following figure.

Viewing a Page Template

Figure 4-5 Viewing a Page Template

 

You can also view a Page Template by visiting its Zope URL directly.

DTML Objects: DTML Documents and DTML Methods

DTML is the "other" Zope facility for the creation of presentation in Zope. Two kinds of DTML objects may be added from the Zope Management Interface: DTML Documents and DTML Methods. Both kinds of objects allow you to perform security-constrained presentation logic. The code placed into DTML objects is constrained by Zope's security policy, which means, for the most part, that they are unable to import all but a set of restricted Python "modules", and they cannot directly access files on your filesystem. This is actually a feature, as it allows site administrators to safely delegate the ability to create DTML to "untrusted" or "semi-trusted" users. For more information about Zope's security features, see Users and Security.

A source of frequent confusion for DTML 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 Methods are meant to hold bits of dynamic content that are to be displayed by other DTML Methods and other kinds of Zope objects. For instance, you might create a DTML Method that rendered the content of a navigation bar or a DTML Method that represented a "standard" header for all of your HTML pages. On the other hand, DTML Documents are meant to hold "document-like" content that can stand on its own. DTML Documents also support properties, while DTML Methods do not. The distinction between DTML Methods and DTML Documents is subtle, and if Zope Corporation had it to do "all over again", DTML Documents would likely not exist. (Editor's aside: Believe me, I almost certainly enjoy writing about the difference less than you like reading about it. ;-) There is more information on this topic in the chapters entitled Basic DTML and Variables and Advanced DTML.

As a general rule, you should use a DTML Method to hold DTML content unless you have a really good reason for using a DTML Document, such as a requirement that the container of your DTML content support object properties.

Creating DTML Methods

Click on the Sales folder and then select DTML Method from the add list. This process will take you to the add form for a DTML Method. Specify the id "SalesStaff" and the title "The Jungle Sales Staff" and click Add. An entry for the new DTML Method object will be displayed in the Contents view of the Workspace pane.

Editing DTML Methods

The easiest and quickest way to edit your newly-created DTML Method is through the management interface. To select your method, click on its name or icon, which will bring up the form shown in the figure below.

Editing a DTML Method

Figure 4-6 Editing a DTML Method

 

This view shows a text area in which you can edit the content of your document. If you click the Save Changes 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 DTML Method. Then add the following HTML content to the textarea:

          <html>          <body>          <h2>Jungle Sales Staff</h2>          <ul>            <li>Tarzan</li>            <li>Cheetah</li>            <li>Jane</li>          </ul>          </body>          </html>

 

Note that the example provided above doesn't do anything "dynamic", it's just some HTML. We will explore the creation of dynamic content with DTML in a later chapter. For now, we're just getting used to using a DTML Method object via the ZMI.

After you have completed the changes to your method, click the Save Changes button. Zope returns with a message telling you that your changes have taken effect.

Viewing a DTML Method

You can view a "rendered" DTML Method in the Workspace frame by clicking its View tab. Click the View tab of the SalesStaff DTML method, and you will be presented with something like the following:

Viewing a Rendered DTML Method

Figure 4-7 Viewing a Rendered DTML Method

 

You can also view a DTML Method by visiting its Zope URL directly.

Uploading an HTML File as Content for a DTML Method

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

Create a text file on your local computer named "upload_dtml.html". Populate it with the following content:

          <html>            <body>              <h1>This is my first uploaded DTML Document!</h1>            </body>          </html>

 

While visiting the Sales folder, select DTML Method from the add menu, which will cause the DTML Method add form to be displayed. 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 "upload_dtml.html" file, type in an id of "upload_dtml" for the new DTML Method and click Add and Edit. After clicking Add and Edit, you will be taken back to the Edit form of your uploaded DTML Method.

Logic Objects: Script (Python) Objects and External Methods

"Logic" objects in Zope are objects which typically perform some sort of "heavy lifting" or "number crunching" in support of presentation objects. When they are executed, they typically do not return HTML or any other sort of structured presentation text. Instead, they typically return values that are easy for a presentation object to format for display. For example, a logic object may return a "list" of "strings". Then, a presentation object may "call in" to the logic object and format the results of the call into a one-column HTML table, where the rows of the table are populated by the strings. Instead of embedding "logic" in a presentation object, you can (and often should) elect to move the logic into a logic object, using a presentation object only to format the result for display. In this manner, you can change or replace the presentation object without needing to "re-code" or replace the logic.

Note that logic objects, like presentation and content objects, are also addressable directly via a URL, and may elect to return HTML, which can be displayed in a browser meaningfully. However, the return value of a logic object can almost always be displayed in a browser, even if the logic object does not return HTML.

There are two kinds of logic objects supported by "stock" Zope: Script (Python) objects and External Methods. An add-on product allows you to code logic in Perl. Several community-contributed Products exist which allow you to use Zope to manage your PHP and JSP scripts, as well, but they are not integrated as tightly as the Python- or Perl-based logic objects. They are PHParser, PHPObject, and ZopeJSP.

The "stock" logic objects, External Methods and Script (Python) objects are written in the syntax of the Python scripting language. Python is a general-purpose programming language. You are encouraged to read the Python Tutorial in order to understand the syntax and semantics of the example Script (Python) objects and External Methods shown throughout this chapter and throughout this book.

One important Python feature that must be mentioned here, however: Python uses whitespace in the form of indentation to denote block structure. Where other languages, such as C, Perl, and PHP might use "curly braces" to express a block of code, Python determines code blocks by examining the indentation of your code text. If you're used to other programming languages, this may take some "getting-used-to" (typically consisting of a few hours of unsavory spoken language ;-). If you have problems saving or executing Script or External Method objects, make sure to check your Script's indentation.

Script (Python) Objects

Script (Python) objects are one kind of logic object. Note that the torturous form of their name (as opposed to "Python Script") is unfortunate: a legal issue prevents Zope Corporation from naming them "Python Scripts", but most folks at Zope Corporation and in the Zope community refer to them in conversation as just that.

Script (Python) objects are "security-constrained" web-editable pieces of code that are written in a subset of the Python scripting language. Not all Python code is executable via a Script (Python) object. Script (Python) objects are constrained by Zope's security policy, which means, for the most part, that they are unable to import all but a set of restricted Python "modules", and they cannot directly access files on your filesystem. This is actually a "feature", as it allows site administrators to safely delegate the ability to create logic in Python to "untrusted" or "semi-trusted" users. For more information about Zope's security features, see Users and Security.

Creating A Script (Python)

Enter the Sales folder you created earlier by clicking on it, then select Script (Python) from the Add list. The add form for the object will be displayed. Specify the id "SalesScript" and click Add. You will see an entry in the Sales folder Content view representing the "SalesScript" Script (Python) object. Its content is standard "boilerplate" text at this point.

Editing A Script (Python)

The easiest way to edit a Script (Python) 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 Script (Python) which gives you a textarea where you can edit the template. Click on the SalesScript icon. You will see something like:

Default Script Content

Figure 4-8 Default Script Content

 

In the Parameter List form element, type name="Chris".

Replace the original content that comes in the "body" (the big TEXTAREA below the Last Modified line) of the Script (Python) object with the following text:

         return 'Hello, %s from the %s script' % (name, script.id)

 

Then click Save Changes at the bottom of the edit form.

Testing A Script (Python)

You can "test" a Script (Python) in the Workspace frame by clicking the Test tab from the Script's management screen. When you test a script, the output of the script will be displayed in your browser. Script testing may require that you provide values for the script's parameters before you can view the results. Click the Test tab of the SalesScript object, and you will see something like the following figure.

Testing a Script

Figure 4-9 Testing a Script

 

In the Value box next to the name parameter, type your name. Then click "Run Script". You will be presented with output in the Workspace frame not unlike:

         Hello, [yourname] from the SalesScript script

 

If a Script does not require parameters or has defaults for its parameters (as does the example above), you may visit its URL directly to see its output. In our case, visiting the URL of SalesScript directly in your browser will produce:

         Hello, Chris from the SalesScript script

 

If a Script does require or accept parameters, you may also influence its execution by visiting its URL directly with a "query string". In our case, visiting the URL http://localhost:8080/Sales/SalesScript?name=Fred will produce the following output:

         Hello, Fred from the SalesScript script

 

Zope maps query string argument values to their corresponding parameters automatically, as you can see by this output.

Uploading A Script (Python)

Uploading the body of a Script (Python) is much like uploading the body of a DTML Method or Page Template. One significant difference is that Script (Python) objects interpret text that is offset by "double-pound" ('##') at the beginning of the text as data about their parameters, title, and "bindings". For example, if you entered the following in a text editor and uploaded it, the lines that start with "double-pound" signs would be interpreted as parameter data, and the only text in the "body" would be the return line. It would appear exactly as our SalesScript did:

        ## Script (Python) "SalesScript"        ##bind container=container        ##bind context=context        ##bind namespace=        ##bind script=script        ##bind subpath=traverse_subpath        ##parameters=name="Chris"        ##title=        ##        return 'Hello, %s from the %s script' % (name, script.id)

 

You may see this view of a Script (Python) object by clicking on the view or download link in the description beneath the "body" textarea.

You may also type the "double-pound" quoted text into the "body" textarea along with the actual script lines and the "double-pound" quoted text will be "automagically" turned into bindings and parameters for the Script.

External Methods

External Methods objects are another kind of logic object. They are very similar to Script (Python) objects. They are scripted in the Python programming language, and they are used for the same purpose. They have a few important differences:

  • They are not editable using the Zope Management Interface. Instead, External Methods "modules" need to be created on the filesystem of your Zope server in a special subdirectory of your Zope directory named Extensions.
  • Because they are not editable via the Zope Management Interface, their execution is not constrained by the Zope "security machinery". This means that unlike Script (Python) objects, they can import and execute essentially arbitrary Python code and access files on your Zope server's file system.
  • They do not support the concept of "bindings" (which we have not discussed much, but please just make note for now).

External methods are often useful as an "escape hatch" when Zope's security policy prevents you from using a Script (Python) or DTML to do a particular job that requires more access than is "safe" in through-the-web-editable scripts. For example, a Script (Python) cannot write to files on your server's filesystem, while an External Method may.

Creating and Editing An External Method File

Minimize the browser you're using to access the Zope Management Interface. Open a "shell" console on the machine which you're using as a Zope server. Navigate to the Zope installation folder. You will encounter a subfolder in the Zope installation folder named Extensions. Navigate into this folder and create a text file there with the name SalesEM.py. Within this file, save the following content:

        def SalesEM(self, name="Chris"):            id = self.id            return 'Hello, %s from the %s external method' % (name, id)

 

Creating an External Method Object

Before you can use an External Method from within Zope, you need to create an External Method object in your Zope Management Interface that "refers to" the function in the file that you just created. Reopen your browser window and visit the Zope Management Interface. Navigate to the Sales folder and select External Method from the Add list. The Add Form for an External Method will appear. Provide an Id of "SalesEM", a Title of "Sales External Method", a Module Name of "SalesEM" and a Function Name of "SalesEM".

Then click Add at the bottom of the add form.

Testing An External Method Object

You can test an External Method in the Workspace frame by clicking the Test tab from the External Method's management screen. When you test an external method, the output of the external method will be displayed in your browser. Unlike Script (Python) objects, External Methods provide no mechanism for specifying parameter values during testing. However, like Script (Python) objects, their output is influenced by values in a query string when you visit them directly.

Click the Test tab of the SalesEM object, and you will see something like the following figure.

Testing an External Method

Figure 4-9 Testing an External Method

 

If an External Method does not require parameters (or has defaults for its parameters, as in the example above), you may visit its URL directly to see its output.

Provide alternate values via a query string to influence the execution of the External Method. For example, visiting the SalesEM external Method via http://localhost:8080/Sales/SalesEM?name=Fred will display the following output:

          Hello, Fred from the Sales external method

 

Alert readers will note that the id provided by the output is not the id of the External Method ('SalesEM'). It is instead the id of the "containing" folder, which is named Sales! This is a demonstration of the fact that External Methods (as well as Script (Python) objects are mostly meant to be used in the "context" of another object, which is often a Folder. This is why they are named methods. Typically, you don't often want to access information about the External Method or Script itself; all the "interesting" information is usually kept in other objects (like Folders). An External Method or Script "knows about" its context and can display information about the context without much fuss.

SQL Methods: Another Kind of Logic Object

SQL Methods are logic objects used to store and execute database queries that you can reuse in your web applications. We don't explain them in this chapter, because we haven't yet explained how to interface Zope with a relational database. SQL Methods are explained in the chapter entitled Relational Database Connectivity, where an example of creating a web application using a relational database is given.

Creating a Basic Zope Application Using Page Templates and Scripts

Here is a simple example of using Zope's logic and content objects to build 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:

  1. You need the following information: your current account balance (or debt) called the "principal", the annual interest rate expressed as a decimal (like 0.095) called the "interest_rate", the number of times during the year interest in compounded (usually monthly), called the "periods" and the number of years from now you want to calculate, called the "years" .
  2. Divide your "interest_rate" by "periods" (usually 12). We'll call this result "i".
  3. Take "periods" and multiply it by "years". We'll call this result "n".
  4. Raise (1 + "i") to the power "n".
  5. Multiply the result by your "principal". This is the new balance (or debt).

 

We will use Page Template and Script objects to construct an application that will perform this task.

For this example, you will need two Page Templates with the ids interestRateForm and interestRateDisplay, respectively to collect the information from the user and display it. You will also need a Script (Python) with an id of calculateCompoundingInterest that will do the actual calculation.

The first step is to create a folder in which to hold the application. In your Zope's root folder, create a folder with the id "Interest". You will create all of the objects which follow within this folder.

Creating a Data Collection Form

Visit the Interest folder by clicking on it within the Zope Management Interface. Within the Interest folder, create a Page Template with the id interestRateForm that collects "principal", "interest_rate", "periods" and "years" from your users. Use this text as the body of your interestRateForm page template:

        <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, when it is submitted, calls the interestRateDisplay template (which we have not yet created).

Creating A Script To Calculate Interest Rates

Now, revisit the Contents view of the Interest folder and create a Script (Python) object with the id calculateCompoundingInterest that accepts four parameters: principal, interest_rate, periods and years. Provide it with the following "body":

        """         Calculate compounding interest.        """        i = interest_rate / periods        n = periods * years        return ((1 + i) ** n) * principal 

 

Remember: you enter the parameter names, separated by commas, into the Parameters List field, and the body into the body text area. Remember also that when you're creating a Script (Python) object, you're actually programming in the Python programming language which is indentation-sensitive. Make sure each of the lines above line up along the very left side of the text area, or you may get an error when you attempt to save it.

Creating A Page Template To Display Results

Next, go back to the Contents view of the Interest folder and create a Page Template with the id interestRateDisplay. This Page Template is called by interestRateForm and calls calculateCompoundingInterest. It also renders and returns the results:

        <html>          <body>          Your total balance (or debt) including compounded interest over          <span tal:define="years request/years;                            principal request/principal;                            interest_rate request/interest_rate;                            periods request/periods">            <span tal:content="years">2</span> years is:<br><br>            <b>$            <span tal:content="python: here.calculateCompoundingInterest(principal,                                                              interest_rate,                                                             periods,                                                             years)" >1.00</span>            </b>          </span>          </body>        </html>

 

Dealing With Errors

In any programming venue, you will need to deal with errors. Nobody's perfect! You may have already encountered some as you've entered these scripts. Let's explore errors a bit by way of an example. In our case, we cannot use the Page Template Test tab to test the interestRateDisplay without receiving an error, because it depends on the interestRateForm to supply it with the variables "years, "principal", "interest_rate" and "periods". It is not directly "testable". For the sake of "seeing the problem before it happens for real", click the Test tab. Zope will present an error page with text not unlike the text below:

          Zope Error          Zope has encountered an error while publishing this resource.          Error Type: KeyError          Error Value: years

 

This error message is telling you that your Page Template makes a reference to a variable "years" that it can't find. If you've created a Site Error Log object in your root folder (it will be named error_log), you can view the full error by visiting the error_log object and clicking the topmost error log entry link which will be name KeyError: years on the Log tab. The error log entry will be displayed. It contains information about the error, including the time, the user who received the error, the URL which caused the error to happen, the exception type, the exception value, and a "Traceback" which typically gives you enough information to understand what happened. In our case, the part of the traceback that is interesting to us is:

         * Module Products.PageTemplates.TALES, line 217, in evaluate           URL: /Interest/interestRateDisplay           Line 4, Column 8           Expression: standard:'request/years'

 

This tells us that the failure occurred when the Page Template attempted to access the variable request/years. We know why: there is no variable request/years, because that variable is only "filled in" as a result of posting via our interestRateForm, which calls in to our interestRateDisplay Page Template, which has the effect of inserting the variables principal, interest_rate, periods and years into request "namespace". We'll cover Page Template namespaces in a succeeding chapter, but for now, let's move on.

Using The Application

Let's use the application you've just created. Visit the interestRateForm Page Template and click the Test tab.

Type in 20000 for balance or debt, .06 for interest rate, 4 for periods in a year, and 20 for number of years and click Calculate. This will cause interestRateForm to submit the collect information to interestRateDisplay, which calls the Script (Python) named calculateCompoundingInterest. The display method uses the value returned by the script in the resulting display. You will see the following result.

Result of the Interest Application

Figure 4-10 Result of the Interest Application

 

If you see something close to this, it calls for congratulations, because you've just built your first Zope application successfully. If you are having troubles, try to troubleshoot the application by using the tips in the section above "Dealing With Errors." If you're stuck entirely, it's advisable that you send a message to the Zope mailing list detailing the problem that you're having in as concise and clear a form as possible. It is likely that someone there will be able to help you. It is polite to subscribe to the maillist itself if you want to receive replies. See the Mailing list section of Zope.org for information about how to subscribe to the Zope (zope@zope.org) maillist.

The Zope Tutorial

Zope comes with a built-in tutorial which reinforces some of the concepts you've learned here. As an extension of this book, we recommend that you run the tutorial to get a feel for using basic Zope objects (particularly DTML objects). To use the tutorial properly, your browser should support JavaScript and cookies.

To launch the tutorial, navigate to the root folder and add a Zope Tutorial object by selecting Zope Tutorial from the add list. When the add form asks for an "id" for the object, give it the id tutorial and click "Add". You will be directed to a screen with a "Begin Tutorial" button. When you click the "Begin Tutorial" button, a new browser window resembling the help system will be opened with the tutorial. If another window does not appear, either your browser does not support JavaScript or it is configured to disallow the opening of new windows. This will prevent you from being able to use the tutorial, so you may want to try a different browser.

If you start the tutorial and want to stop using it before you have completed all the lessons, you can later return to the tutorial. Just go to the help system and find the lesson you'd like to continue with by visiting the help system and navigating to the Zope Tutorial help category. There is no need to re-install the tutorial.