Deutsche Zope User Group
Gast 2 Benutzer online
DZUG-News

Zopebuch: Inhaltsverzeichnis

Dieses Dokument wird momentan �bersetzt und ist zur Zeit leider teilweise noch in Englisch vorhanden.

Kapitel 6: Erstellen einfacher Zope-Anwendungen

In Kapitel 3, "Benutzen einfacher Zope-Objekte" und Kapitel 4, "Dynamischer Inhalt mit DTML" lernten Sie grundlegende Zope-Objekte und DTML kennen. In diesem Kapitel werden Sie erfahren, wie Sie einfache, aber leistungsfähige Web-Anwendungen mit Hilfe dieser Mittel. In späteren Kapiteln dieses Buches werden Sie etwas über vielschichtigere Objekte und komplizierteres DTML erfahren. Wie auch immer, die in diesem Kapitel besprochenen Design-Techniken werden auch später angewendet.

Anmerkung: in Kapitel 3, "Einfache Zope-Objekte", erklärten wir, inwiefern "Zope Page Templates" neu für Zope sind und dass sie für Präsentationen benutzt werden sollten. Wir haben dieses Kapitel allerdings noch nicht von DTML auf "Page Templates" umgestellt, werden es aber bald, um die neuen - auf "Page Templates" basierenden - Methodiken darzustellen, überarbeiten.

Erstellen von Anwendungen mit Hilfe von Ordnern

Ordner sind die "grundlegenden Bausteine" jeder Zope-Anwendung. Sie erlauben Ihnen die Organisation Ihrer Zope-Objekte und aktives Teilnehmen in Ihren Web-Anwendungen. Ordner bekommen durch das Hinzufügen von Skripten ein Verhalten.

Skripte und Ordner arbeiten zusammen, um einfache Anwendungen zu realisieren. Ordner stellen die Informations-Struktur und ein Rahmenwerk für das Verhalten Ihrer Site zur Verfügung. Später in diesem Kapitel wird Ihnen ein Beispiel dieses Design-Konzeptes anhand einer einfachen Gästebuch-Anwendung vorgestellt. Ein Ordner wird zum Bereithalten der Methoden, Skripte und Daten der Gästebuch-Anwendung benutzt. Die Skripte stellen das Verhalten zur Verfügung, die Methoden sind für die Darstellung der Anwendung verantwortlich.

Nehmen Sie - als Beispiel - an, Sie haben einen Ordner Rechnungen um Rechnungen zu speichern. Sie könnten 2 Objekte RechnungHinzufuegen und RechnungBearbeiten in diesem Ordner erzeugen, welche Ihnen erlauben, Rechnungen hinzuzufügen beziehungsweise zu bearbeiten. Jetzt wäre Ihr Rechnungen-Ordner eine kleine Anwendung.

(A. d. Übersetzers): Diese Objekte könnten Skripte oder Methoden sein, die entsprechende Funktionalität muss von Ihnen implementiert werden. Genaueres dazu finden Sie im Kapitel 4 und 10.

Zope's simple and expressive URLs are used to work with the invoices application.

Wie Sie gesehen haben, können Sie Zope Objekte anzeigen, indem Sie die entsprechende URL in Ihrem Browser aufrufen. So ruft, zum Beispiel, die URL http://localhost:8080/Rechnungen/RechnungHinzufuegen das Objekt RechnungHinzufuegen im Ordner Rechnungen auf. Diese URL könnte Sie zu einer Eingabemaske führen, auf der Sie Rechnungen hinzufügen können. Auf die gleiche Art würde die URL http://localhost:8080/Rechnungen/RechnungBearbeiten?rechnungs_nummer=42 das Objekt RechnungBearbeiten im Rechnungen-Ordner aufrufen und ihm das Argument rechnungs_nummer mit dem Wert 42 übergeben. Diese URL könnte Sie zu einer Maske führen, in der Sie die Rechnung mit der Nummer 42 editieren können.

Aufrufen von Objekten in Ordnern mit Hilfe von URLs

Das Beispiel Rechnungen veranschaulicht eine nützliches Zope-Eigenschaft. Sie können Objekte in Ordnern aufrufen, indem Sie zu einer URL gehen, die aus der URL des Ordners gefolgt von der ID des Objektes besteht. Dieses Verfahren wird überall in Zope benutzt und ist ein sehr allgemeines "design pattern". Sie sind nicht darauf beschränkt, nur Objekte in Ordnern aufzurufen - Sie werden später sehen, dass Sie die gleiche URL-Technik auf alle Objekte (nicht nur Ordner) anwenden können.

Nehmen wir als Beispiel an, Sie wollen ein Objekt OrdnerBetrachten in einem Ihrer Ordner aufrufen. Vielleicht haben Sie viele verschiedene OrdnerBetrachten-Objekte an unterschiedlichen Stellen. Zope findet heraus, welches OrdnerBetrachten Sie meinen, indem es zuerst in dem Ordner sucht, in dem Sie das Objekt aufgerufen haben. Findet es das Objekt nicht, sucht Zope in dem darüberliegenden Ordner. Ist es dort nicht zu finden, wird in dem darüberliegenden Ordner gesucht. Dieser Prozess wird solange fortgeführt, bis Zope das Objekt findet oder der Wurzelordner (A. d. Übersetzers: zum Beispiel "http://localhost:8080/") erreicht ist. Wird das Objekt auch dort nicht gefunden, gibt Zope auf und wirft eine Ausnahme.

Sie werden dieses dynamische Verhalten an vielen verschiedenen Stellen in Zope wiedersehen. Diese Technik wird acquisition genannt. Ein Ordner akquiriert ein Objekt, indem er in seinen Kontainern sucht.

Das besondere Objekt index_html

Wie Sie gesehen habe, können Sie alle Arten von Objekten akquirieren. Es ein besonderes Objekt, das Zope dazu benutzt, einen Ordner anzuzeigen. Es heisst index_html.

Das index_html-Objekt stellt eine Standard-Darstellung des Ordners zur Verfügung. Es ist vergleichbar dazu, wie eine index.html als Standard-Darstellung für einen Ordner bei Apache- oder anderen Webservern dient.

Wenn Sie ein Objekt index_html in Ihrem Rechnungen-Ordner erzeugen und dann auf den "View"-Tab klicken oder die URL http://localhost:8080/Rechnungen/ besuchen, wird Zope das Objekt index_html im Ordner Rechnungen aufrufen.

Ein Ordner kann ein index_html-Objekt genauso von seinem Vater-Ordner akquirieren, wie es jedes beliebige Objekt akquirieren kann. Sie können dieses Verhalten dazu benutzen, vielen (Unter-)Ordnern ein vorgegebenes Aussehen zu geben. Um ein abweichendes Aussehen für einen bestimmten Ordner zu erreichen, erzeugen Sie einfach ein neues index_html-Objekt in dem entsprechenden Ordner. Auf diese Weise können Sie das in dem index_html-Objekt im Vater-Ordner vordefinierte Aussehen überschreiben.

Erstellung der Zope Zoo Webseite

In diesem Abschnitt werden Sie eine einfache Webseite für den Zope Zoo erstellen. Als Webmaster des Zoos ist es Ihr Job, die Seite benutzbar und wartbar zu machen. Hier ein paar Dinge, die Sie bachten müssen:

  • Die Benutzer des Zoos müssen genauso einfach durch den Zoo laufen können, wie in einem echten Zoo.
  • Alle gemeinsamen Layout-Tools, wie zum Beispiel Cascading Style Sheets (CSS), müssen an einer einfach zu wartenden Stelle platziert sein.
  • Sie müssen eine einfache Datei-Bibliothek von, die Tiere beschreibenden, Dokumenten verfügbar mache.
  • Sie benötigen eine site map, so dass Ihre Besucher schnell einen Eindruck vom Aufbau des Zoos bekommen.
  • Ein Gästebuch muss erzeugt werden, damit Besucher Ihnen Rückmeldungen und Kommentare über Ihre Seite zukommen lassen können.
  • Ein Abschnitt "What's new" muss erstellt werden, der den Besuchern mitteilt, welche Äderungen sich vor Kurzem ereignet haben.

Im Zoo navigieren

Damit die Navigation funktioniert benötigt Ihre Seite ein paar einfache Strukturen. Erzeugen Sie eine Handvoll Ordner, die die Struktur des Zoos abbilden. Benutzen Sie dafür das folgende Layout (siehe Abbildung 5-1).

Zoo Ordner-Struktur.

Abbildung 5-1 Zoo Ordner-Struktur.

Die Hauptstruktur des Zoos enthält 3 übergeordnete Ordner, Reptiles, Mammals und Fish. Um in Ihrem Zoo zu navigieren sollten die Besucher zuerst Ihre Hauptseite besuchen. Anschließend können Sie einen der 3 übergeordneten Ordner anklicken, um einen bestimmten Bereich des Zoos zu betreten. Sie sollten außerdem ein ähnliches Prinzip benutzen können, um tiefer in den Zoo, zum Beispiel zur snakes-Abteilung, vorzudringen. Dem Besucher sollte es zusätzlich möglich gemacht werden, einen Abschnitt wieder zu verlassen und in einen übergeordneteren Bereich zu kommen.

Diese Arbeiten können mit Zope auf einfache Weise gelöst werden. Erstellen Sie eine DTML-Methode (DTML Method) navigation mit folgendem Inhalt in Ihrem ZopeZoo-Ordner:

    

Diese, gerade von Ihnen erzeugte Methode, generiert eine Liste mit Links zu den verschiedenen Unter-Abschnitten Ihres Zoos. Es ist wichtig zu wissen, dass diese Methode in jedem Ordner arbeiten kann, da sie keine Annahmen über den enthaltenden Ordner macht. Da wir die Methode im ZopeZoo-Ordner abgelegt haben, kann jeder Zoo-Ordner diese Methode akquirieren.

Now, you need to incorporate this method into the site. Let's put a reference to it in the standard_html_header object so that the navigation system is available on every page of the site. Your standard_html_header could look like this:

        
        <dtml-var title></dtml-var>
        
        

Next we need to add a front page to the Zoo site and then we can view the site and verify that the navigation works correctly.

Adding a Front Page to the Zoo

Now, you need a front page that serves as the welcome screen for Zoo visitors. Let's create a DTML Method in the ZopeZoo folder called index_html with the following content:

        

          

Welcome to the Zope Zoo

Here you will find all kinds of cool animals. You are in the section.

Take a look at how your site appears by clicking on the View tab in the root folder, as shown in Figure 5-2.

Zope Zoo front page.

Figure 5-2 Zope Zoo front page.

Here you start to see how things come together. At the top of your main page you see a list of links to the various subsections. These links are created by the navigation method that is called by the standard_html_header method.

You can use the navigation links to travel through the various sections of the Zoo. Use this navigation interface to find the reptiles section.

Zope builds this page to display a folder by looking for the default folder view method ,index_html. It walks up the zoo site folder by folder until it finds the index_html method in the ZopeZoo folder. It then calls this method on the Reptiles folder. The index_html method calls the standard_html_header method which in turn calls the navigation method. Finally, the index_html method displays a welcome message and calls the standard_html_footer.

What if you want the reptile page to display something besides the welcome message? You can replace the index_html method in the reptile section with a more appropriate display method and still take advantage of the zoo header and footer including navigation.

In the Reptile folder create a DTML Method named index_html. Give it some content more appropriate to reptiles:

        

        

The Reptile House

Welcome to the Reptile House.

We are open from 6pm to midnight Monday through Friday.

Now take a look at the reptile page by going to the Reptile folder and clicking the View tab.

Since the index_html method in the Reptile folder includes the standard headers and footers, the reptile page still includes your navigation system.

Click on the Snakes link on the reptile page to see what the Snakes section looks like. The snakes page looks like the Reptiles page because the Snakes folder acquires its index_html display method from the Reptiles folder.

Improving Navigation

The navigation system for the zoo works pretty well, but it has one big problem. Once you go deeper into the site you need to use your browser's back button to go back. There are no navigation links to allow you to navigate up the folder hierarchy. Let's add a navigation link to allow you to go up the hierarchy. Change the navigation method in the root folder:

        Return to parent

Now browse the Zoo site to see how this new link works, as shown in Figure Figure 5-3.

Improved zoo navigation controls.

Figure 5-3 Improved zoo navigation controls.

As you can see, the Return to parent link allows you to go back up from a section of the site to its parent. However some problems remain; when you are at the top level of the site you still get a Return to parent link which leads nowhere. Let's fix this by changing the navigation method to hide the parent link when you're in the ZopeZoo folder:

        
          Return to parent

Now the method tests to see if the current object has any parents before it display a link to the parent. PARENTS is a list of the current object's parents, and len is a utility function which returns the length of a list. See Appendix A for more information on DTML utility functions. Now view the site. Notice that now there is no parent link when you're viewing the main zoo page.

There are still some things that could be improved about the navigation system. For example, it's pretty hard to tell what section of the Zoo you're in. You've changed the reptile section, but the rest of the site all looks pretty much the same with the exception of having different navigation links. It would be nice to have each page tell you what part of the Zoo you're in.

Let's change the navigation method once again to display where you are:

        
          

Section

Return to parent

Now view the site again.

Zoo page with section information.

Figure 5-4 Zoo page with section information.

As you can see in Figure 5-4, the navigation method now tells you what section you're in along with links to go to different sections of the zoo.

Factoring out Style Sheets

Zoo pages are built by collections of methods that operate on folders. For example, the header method calls the navigation method to display navigation links on all pages. In addition to factoring out shared behavior such as navigation controls, you can use different Zope objects to factor out shared content.

Suppose you'd like to use CSS (Cascading Style Sheets ) to tailor the look and feel of the zoo site. One way to do this would be to include the CSS tags in the standard_html_header method. This way every page of the site would have the CSS information. This is a good way to reuse content, however, this is not a flexible solution since you may want a different look and feel in different parts of your site. Suppose you want the background of the snakes page to be green, while the rest of the site should have a white background. You'd have to override the standard_html_header in the Snakes folder and make it exactly the same as the normal header with the exception of the style information. This is an inflexible solution since you can't vary the CSS information without changing the entire header.

You can create a more flexible way to define CSS information by factoring it out into a separate object that the header will insert. Create a DTML Document in the ZopeZoo folder named style_sheet. Change the contents of the document to include some style information:

        

This is a CSS style sheet that defines how to display h1, p and body HTML tags. Now let's include this content into our web site by inserting it into the standard_html_header method:

        
        
        
        
        
        

Now, when you look at documents on your site, all of their paragraphs will be dark red, and the headers will be in a sans-serif font.

To change the style information in a part of the zoo site, just create a new style_sheet document and drop it into a folder. All the pages in that folder and its sub-folders will use the new style sheet.

Creating a File Library

File libraries are common on web sites since many sites distribute files of some sort. The old fashioned way to create a file library is to upload your files, then create a web page that contains links to those files. With Zope you can dynamically create links to files. When you upload, change or delete files, the file library's links can change automatically.

Create a folder in the ZopeZoo folder called Files. This folder contains all of the file you want to distribute to your web visitors.

In the Files folder create some empty file objects with names like DogGrooming or HomeScienceExperiments, just to give you some sample data to work with. Add some descriptive titles to these files.

DTML can help you save time maintaining this library. Create an index_html DTML Method in the Files folder to list all the files in the library:

        

        

File Library

Now view the Files folder. You should see a list of links to the files in the Files folder as shown in Figure 5-5.

File library contents page.

Figure 5-5 File library contents page.

If you add another file, Zope will dynamically adjust the file library page. You may also want to try changing the titles of the files, uploading new files, or deleting some of the files.

The file library as it stands is functional but Spartan. The library doesn't let you know when a file was created, and it doesn't let you sort the files in any way. Let's make the library a little fancier.

Most Zope objects have a bobobase_modification_time method that returns the time the object was last modified. We can use this method in the file library's index_html method:

        

        

File Library

File Last Modified

The new file library method uses an HTML table to display the files and their modification times.

Finally let's add the ability to sort this list by file name or by modification date. Change the index_html method again:

        

        

File Library

File Last Modified

Now view the file library and click on the File and Last Modified links to sort the files. This method works with two sorting loops. One uses the in tag to sort on an object's id. The other does a reverse sort on an object's bobobase_modification_time method. The index_html method decides which loop to use by looking for the sort variable. If there is a sort variable and if it has a value of date then the files are sorted by modification time. Otherwise the files are sorted by id.

Building a Guest Book

A guest book is a common and useful web application that allows visitors to your site to leave messages. Figure Figure 5-6 shows what the guest book you're going to write looks like.

Zoo guest book.

Figure 5-6 Zoo guest book.

Start by creating a folder called GuestBook in the root folder. Give this folder the title The Zope Zoo Guest Book. The GuestBook folder will hold the guest book entries and methods to view and add entries. The folder will hold everything the guest book needs. After the guest book is done you will be able to copy and paste it elsewhere in your site to create new guest books.

You can use Zope to create a guest book several ways, but for this example, you'll use one of the simplest. The GuestBook folder will hold a bunch of DTML Documents, one document for each guest book entry. When a new entry is added to the guest book, a new document is created in the GuestBook folder. To delete an unwanted entry, just go into the GuestBook folder and delete the unwanted document using the management interface.

Let's create a method that displays all of the entries. Call this method index_html so that it is the default view of the GuestBook folder:

        

        

Sign the guest book

On , said:

This method loops over all the documents in the folder and displays each one. Notice that this method assumes that each document will have a guest_name property. If that property doesn't exist or is empty, then Zope will use Anonymous as the guest name. When you create a entry document you'll have to make sure to set this property.

Next, let's create a form that your site visitors will use to add new guest book entries. In the index_html method above we already created a link to this form. In your GuestBook folder create a new DTML Method named addEntryForm:

        

        

Type in your name and your comments and we'll add it to the guest book.

Your name:

Your comments:

Now when you click on the Sign Guest Book link on the guest book page you'll see a form allowing you to type in your comments. This form collects the user's name and comments and submits this information to a method named addEntryAction.

Now create an addEntryAction DTML Method in the GuestBook folder to handle the form. This form will create a new entry document and return a confirmation message:

        

        

        

Thanks for signing our guest book!

Return to the guest book.

This method creates a new entry by calling the addEntry method and returns a message letting the user know that their entry has been added.

The last remaining piece of the puzzle is to write the script that will create a document and sets its contents and properties. We'll do this in Python since it is much clearer than doing it in DTML. Create a Python-based Script in the GuestBook folder called addEntry with parameters guest_name and comments:

        ## Script (Python) "addEntry"
        ##parameters=guest_name, comments
        ##
        """
        Create a guest book entry.
        """
        # create a unique document id
        id='entry_%d' % len(context.objectIds())

        # create the document
        context.manage_addProduct['OFSP'].manage_addDTMLDocument(id,
                                                 title="", file=comments)

        # add a guest_name string property
        doc=getattr(context, id)
        doc.manage_addProperty('guest_name', guest_name, 'string')

This script uses Zope API calls to create a DTML Document and to create a property on that document. This script performs the same sort of actions in a script that you could do manually; it creates a document, edits it and sets a property.

The guest book is now almost finished. To use the simple guest book, just visit http://localhost:8080/GuestBook/.

One final thing is needed to make the guest book complete. More than likely your security policy will not allow anonymous site visitors to create documents. However the guest book application should be able to be used by anonymous visitors. In Chapter 7, User and Security, we'll explore this scenario more fully. The solution is to grant special permission to the addEntry method to allow it to do its work of creating a document. You can do this by setting the Proxy role of the method to Manager. This means that when the method runs it will work as though it was run by a manager regardless of who is actually running the method. To change the proxy roles go to the Proxy view of the addEntry method, as shown in Figure 5-7.

Setting proxy roles for the addEntry method.

Figure 5-7 Setting proxy roles for the addEntry method.

Now select Manager from the list of proxy roles and click Change.

Congratulations, you've just completed a functional web application. The guest book is complete and can be copied to different sites if you want.

Extending the Guest Book to Generate XML

All Zope objects can create XML. It's fairly easy to create XML with DTML. XML is just a way of describing information. The power of XML is that it lets you easily exchange information across the network. Here's a simple way that you could represent your guest book in XML:

        
          
            My comments
          
          
            I like your web page
          
          
            Please no blink tags
          
        

This XML document may not be that complex but it's easy to generate. Create a DTML Method named "entries.xml" in your guest book folder with the following contents:

        
          
          
            
          
          
        

As you can see, DTML is equally adept at creating XML as it is at creating HTML. Simply embed DTML tags among XML tags and you're set. The only tricky thing that you may wish to do is to set the content-type of the response to text/xml, which can be done with this DTML code:

        

The whole point of generating XML is producing data in a format that can be understood by other systems. Therefore you will probably want to create XML in an existing format understood by the systems you want to communicate with. In the case of the guest book a reasonable format may be the RSS (Rich Site Summary) XML format. RSS is a format developed by Netscape for its my.netscape.com site, which has since gained popularity among other web logs and news sites. The Zope.org web site uses DTML to build a dynamic RSS document.

Congratulations! You've XML-enabled your guest book in just a couple minutes. Pat yourself on the back. If you want extra credit, research RSS enough to figure out how to change entries.xml to generate RSS.

The Next Step

This chapter shows how simple web applications can be made. Zope has many more features in addition to these, but these simple examples should get you started on create well managed, complex web sites.

In the next chapter, we'll see how the Zope security system lets Zope work with many different users at the same time and allows them to collaborate together on the same projects.