Zope Web Application Contstruction Kit: Chapter 5, "CMF"
Copyright Sams Publishing, 2001. All rights reserved.Last Modified Mar 27, 2001.
The contents of this chapter are licensed under the Open Publication License v1.0 without any options. This book is still in development.
Your comments regarding the content are welcome, and should be addressed to:
[email protected]. Serious contributions will be acknowledge in the book.
Chapter 05
The Content Management Framework (CMF)
The Content Management Framework (CMF) previously known as the Portal Toolkit (PTK) is part of Digital Creations strategy to create a framework for building Content Management Systems and Portals.This means that the product we refer to in this book CMF-1.0 is an implementation or example of the CMF but not the CMF itself. Why make this distinction? For Portals and Content Management Systems to be useful they need to be customized so that they incorporate the workflow of how the site is to be used. While the majority of core services in a Portal or CMS are identical it is the differences that typically take the most time to develop to a particular organizations needs.
The CMF core services as outlined in the Introduction to CMF
http://cmf.zope.org/doc/introduction.txt
and written by Paul Everitt are:
MembershipServices (includes personalization) CatalogingServices (using Zope�s ZCatalog) WorkflowServices BasicContentServices SiteDesignServices IntegrationServices DiscussionServices ArchivingServices SyndicationServices RatingServices TestingServicesWe think the best way to visualize how the Content Management Framework can help developers is by seeing it as a well built foundation for the attachment of components. These components can be services in the form of software (such as a threaded web discussion board) or components such as �WorkflowServices� which define how users can interact with a website.
What can the CMF do for you?
The CMF is a great foundation for starting your portal. It anticipates particular needs but respects diversity. This means that the CMF will includes several simple applications and workflows but you will be able to selectively take components out and replace them with your own. A theme that you�ll hear over and over again in this book is how using the Zope and in this case CMF infrastructure you can save yourself a lot of time.People at D.C. and within the Zope community spend a lot of time thinking about how this portal and content infrastructure can be designed to accommodate more than one usage case. By using the CMF you are essentially benefiting from the experience of hundreds of development hours by developers all over the world who have created more portals than you are likely to create in your lifetime.
For example built into the CMF are things such as �Topics� which allow members to create custom views of data in the CMF such as �all Press Releeases about Achievers International within the last two weeks� and keep track of topics which interest them when they log into their portal workspace. Additionally, members can use features similar to a bookmark in a browser to quickly jump to resources they find particularly useful within the portal via a feature called �Favorites�.
If an online community is to thrive then members must be able to contribute. On Zope.org for example members can contribute content like how-to�s, news articles, as well as setup their own personal homepage and upload any Zope products they may have created.
To address the growing needs of the Zope community D.C. has recently launched two new portal websites:
dev.zope.org cmf.zope.org
Each of these websites has a particular focus and therefore provides slightly different services to its users.
dev.zope.org
This portal is designed for the discussion and the management of new features in Zope as well as products deemed important to the continued expansion of the Zope community. In contrast to Zope.org it does not provide services such as personal homepages.
cmf.zope.org
The official website for developers interested in or working with the Content Management Framework. It uses the latest version of the CMF software and like Zope.org allows users to join and upload their own files such as �skins� which they may want to contribute to the community. Users can also create custom views to data available on the portal including �Topics� as well as links called �Favorites� which allow the user to quickly jump to their favorite sections or pages on the Portal.
Installation
Installing the CMF is as simple as any other Zope product.Download the product file.
Unzip the file either in the Zope directory or the product directory, depending on how the product was zipped.
Restart your Zope server.
These three steps are therefore valid for installing any product you can find on Zope.org, ZopeTreasures.com, or any other site containing one or more Zope products.
The actual installation takes place in step three, when the Zope server is restarted. Every Zope product contains an initiation file (__init__.py) which is compiled on a restart. When compiled, this file causes the product to be acknowledged by Zope. If there is a problem during the compilation, the product will not be installed correctly and you will not be able to use the product in your Zope installation.
Download
You can download the latest version of the reference implementation via the CMF websitehttp://cmf.zope.org/download
Make sure that you have the right version of Zope installed. All CMF examples within this book use Zope version 2.3.1 Therefore, if you have an older Zope version, you will need to upgrade before you will be able to use the Content Management Framework.
You should visit Zope.org and cmf.zope.org frequently to stay up-to-date about new products and latest versions of existing products.
Now that you have downloaded the appropriate file(s), we can move on with the installation.
Unzipping the Product File
Depending on your operating system, there are different ways to unpack the product file. With a Windows system, you will need Winzip or a similar program that can handle zip files as well as tar and gzip files. With Linux or UNIX use tar to unzip the file. (e) Windows System (Using Winzip) If your Winzip was installed correctly, you should be able to unzip the CMF file by simply double-clicking it in the Windows Explorer. Winzip may tell you that there is one compressed file in the packed file and ask you whether you wish to decompress it. Answer with yes and then extract the decompressed files to the directory of your Zope installation. Winzip creates a new directory, e.g. CMF-1.0beta, containing three subdirectories in your Zope directory:CMFCore CMFDefault CMFTopicMove those directories and their content to the directory
Zope-directory/lib/python/Products/
The last step of installing the CMF is to restart your Zope server. Go on to "Restarting the Zope Server" to see how to do this.
Linux System
The first step on installing the CMF is to copy or move the packed CMF file to your Zope directory. Now extract the file using the following command:tar �xzvf CMF-1.0.tar.gz
This will create a directory CMF-1.0beta in your Zope directory. This directory contains three subdirectories:
CMFCore CMFDefault CMFTopicCopy or move these directories to the Products directory:
Zope-directory/lib/python/Products/
Now restart your Zope server and the installation is complete.
Restarting the Zope Server
To restart the Zope server, go to the Zope directory and execute the start script. On Windows, this start script is called start.bat and can be executed by simply double-clicking on it in the Windows Explorer. If it is already running, shut it down before restarting.On a Linux machine the start script is just called start. To execute the script, type in
./start &
at the prompt. Make sure to shut down the Zope process before restarting it. You can do that by using the stop script like this:
./stop
Achievers International � ZWACK Use Case
In this book will show how we solve the real world needs of a non-proft organization, Achievers International, by building this organization both a a portal using Zope and the Content Management Framework. In later chapters we will then show how to roll out additional services to the members of the Portals in the form of Zope Products.About Achievers International
Achievers International helps students form companies, and learn how to become entrepenuers by responsibility and helping them slip into roles such as CEO, VP Marketing, etc. Achievers International then teams up different student companies world wide. These schools then import and export various goods and try to sell them at a profit. If profits are made students can decide how to spend the money. Since its inception 21 schools and 4,600 students on 5 continents have participated in the program. Since Achievers International promotes modern technologies such as Videoconferencing and Internet Technologies to prepare students for the challenges of a global marketplace, helping them build a Portal using Zope and the new Content Management Framework (CMF) seemed like a great idea. To find out more about Achievers International and to see the Zope portal in action visit http://www.achieversinternational.org NOTE TO READERS � THIS IS NOT A CMF PORTAL YET -Goals
Regardless of who you build Web Applications for real value is created when technology can be woven to fit the needs of a real organization. Since Achievers International members are all over the globe the Portal has to keep all members informed and up-to-date through a constant flow of pertinent information. So the goal is to provide the software infrastructure to People such as Students or Teachers must be able to publish articles and discuss information. For this purpose we will be using different products and features of the CMS to create the following services:- threaded web discussion area based on ZDiscussions
- Content Management System for News Articles (using MetaPublisher)
- Polls (using the Poll Product)
- Surveys (using PMP Survey)
- Downloadable Help Files and Starter Kits for students (CMF)
What kind of content do do you need to publish foresee?
Who (which group) gets to decide when for example and article is displayed?
Once we felt that we had understood the answers Karen and Norma had given us we were able to define the following core roles:
Administrators Teachers StudentsWe then created the following profiles to better understand how they would interact with the Portal.
Administrators
Administrators are employees or volunteers of Achievers International who watch over and have the final decision about what content belongs on the website.They are able to remove any content they don�t deem acceptable and can approve articles or information via the portals Content Management System (CMS) from students and teachers. Additionally, AI employess will be able to create surveys and polls (see Chapter 8).
They can also add/approve/suspend users who sign up with the Portal.
Teachers
Teachers or Co-ordinators act as a coaches giving advice to the students. The AI Portal will need to provide a section only for co-ordinators to share information on educational/training issues.Students
Since the portal is essentially built to meet needs of the students, students who live in different parts of the world, we will need to provide them with software based services which will allow them to collaborate and exchange information online.These software services will include a Web threaded web discussion forum (see Chapter 7) a content Management System (see Chapter 6) and a repository of support files designed to help them with the program.
Additional Roles
At later stages of this project we may decide to add additional roles such as �Discussion Moderators� who could be real business experts who volunteer and share their knowledge with students via the web discussion boards.The permissions of these experts would have to be narrowly defined, which thanks to the Zope Management Interface (ZMI) is just a series of clicks to create and define new roles.
< show picture of management screen>
Preconditions
The Achievers International Website like the majority of websites on the net is made up of static pages and cgi scripts.When importing an existing website into Zope several options exist. The most straightforward is to use a FTP or WebDAV client.
If your ISP or System Administrator are running your Zope server with Apache instead of ZServer you will not be able to access your installation via either FTP or WebDAV protocols since at this time ZServer is only capable of handling these protocols for Zope.
One Zope Product �load_site�
http://www.zope.org/Members/itamar/load_site
will allow for you to get around this problem by uploading multiple files via the http protocol.
In this case we chose to simply FTP the original Achievers International files via FTP using ZServer and Zope.
Rapid Application Development (RAD)
One of the greatest strengths of Zope is that with the development infrastructure it provides as well as the over 250 Zope Products that exist for Zope today, developers will find few reasons to reinvent the wheel.With Zope Products you will likely be able to save several days of development time, by modifying existing code instead of building an application from scratch.
Because Zope is also an application server you�ll also notice over time that the skills you learn to build one type of application will be useful to build a completely different type of application.
We hope that by the end of this book you�ll see what we mean and will be able to compare this to your previous experiences learning and integrating various different vendor solutions.
Using the requirements of Achievers International we hope introduce you to some of the more interesting Zope Products and how these can be modified to help a real world organization.
Working with the CMF
Getting Started
Now, that you have installed the CMF correctly to your Zope installation, you can start working with it. This is done by creating instances of this product in the Zope management screen.So, the first thing to do is enter the management screen of your Zope installation. Open your browser and enter the URL
http://localhost:8080/manage
or a different URL according to the domain where you installed Zope.
This leads directly to the management screen. You can either add a new portal here in the root directory or create a folder first. A folder may be the better solution if you intend to add more than one portal and wish to keep them together.
After you have decided where to add the portal, choose 'CMF Site' from the drop-down menu at the top of the list contained in the current folder. The following page consists of a form with these text fields:
Id Title Membership source DescriptionId and Title are typical for all objects in Zope. The Id is part of the URL that leads to an object, such as the portal. Therefore, the Id must not conain special characters � except for the underscore (_) or the hiven (-). It may also contain spaces since Zope replaces the space with a URL conform %20.
The membership source is a select box. You can choose between letting the CMF create a new user folder or using your own existing user folder.
The description field allows you to give a short description of the purpose of the portal which will later appear on the portal's homepage. Fill out the 'Add Portal' form with the following data:
Id: AchieversInternational Title: Portal Membership source: Create a user folder in the portal Description: This portal is a means for students and teachers to interact with each others.After you have clicked the Add button, the portal is created and the frame of browser will show a welcome page of the portal.
***05FIG01.gif***
Figure 05.01.
The CMF's welcome page.
The welcome page advises you to first go to the configuration form. This form is used to configure the portal's settings or options. It contains fields to change the portal's apparent email information � Portal 'From' name, Portal 'From' address �, the SMTP server and some options concerning the portal's properties � Portal title, Portal description � as well as the Password policy.
***05FIG02.gif***
Figure 05.02. The portal's configuration options.
All the fields can be chosen freely except for the SMTP server field. You need to enter a valid SMTP server here, or emails sent by the portal will not be sent and may produce an error.
The different Main Pages of the Portal
There are four major pages in the portal: the homepage, the members page, the news page and the search page.These four pages can always be reached by clicking on the respective link in the top bar of the portal.
The Portal's Homepage
Click the link 'home' to go to the portal's homepage. You can find the link in the list of links at the right top of the page. The homepage consists of four parts:The top bar contains the Zope logo, the list of links mentioned above and a search form. On the left, you find the so-called action box. The contents of this box varies from user to user depending on the users rights to execute actions and on the user's current position within the portal. However, the top of this box always shows the name of the user that is currently logged on. On the right, there is a news box. This box contains published News Items sorted by date with the latest News Item at the top. It also contains a link 'more...' which leads to the news pages where listed with their lead-in. The fourth part of the homepage is the overview part. Here the description of the portal is shown.
***05FIG03.gif***
Figure 05.03. The portal's homepage.
The top bar and the action box are consistent throughout the portal. The overview and the news box are only on the homepage.
The Member Page
Go to the members page by clicking the link 'members' in the top bar. This page lists the portal member that want to be shown here. You can move through the list of members by using the Previous and Next links if there are more members than the number given in the field between the two links. The default number of listed members is 25 but you can change this number � and press enter � and the list will change accordingly.
***05FIG04.gif***
Figure 05.04. The portal's member page.
As a portal administrator, you are able to see all member names, not just the ones that want to be seen. After each member name you can also see whether that member allowed to be listed on this page.
***05FIG05.gif***
Figure 05.05. Administrator's view of the member page.
On how a member can decide whether he/she wants to be listed on the member page, see 'The Actions Box � Preference'.
The News Page
Click on the 'news' link in the top bar to go to the news page. This page lists all published news with their title, author, description and the date they were published. Again the latest news is at the top of the list.
***05FIG06.gif***
Figure 05.06. The portal's news page.
To read the full news of a news item, click on the title of the item. The following page show the full body of the news.
***05FIG07.gif***
Figure 05.07. One news item.
The Search Page
There are two ways to search the portal: by simple or advanced search. The simple way to search is typing the word(s) you are looking for into the search field in the top bar and pressing enter or clicking the go button. This search will go through the titles, descriptions and bodies of every accessible object.To use the advanced search, click on the 'search' link in the top bar and the search page appears.
***05FIG08.gif***
Figure 05.08. The portal's search page.
A member has the following options to narrow the search:
Full text Title Description Find items since... Item type creatorThe administrator has an additional box: Review status. That way he can determine whether the objects he is looking for are to be private, pending and/or published.
The Actions Box
As mentioned above, the actions box contains different actions depending on the user's permissions and the current page.Preferences
As mentioned above, every user can choose whether he/she wants to be listed on the members page. They can do so on their preferences page. Click on the link 'preferences' in the action box.
***05FIG09.gif***
Figure 05.09. The preferences page of a member.
On this page, a member can also change his/her email address and which skin he/she wants their portal to have. Skins will be explained later in this chapter.
At the top of the form there is also a link to a page where the member can change his/her password.
Logout
The link 'Logout' is used to log out of the portal. If you are also logged in to Zope, you may need to log out there too in order to fully log out.Add to favourites
A member can create favourites to published objects, such as news items, documents, etc. that he/she may want to visit again so that those objects are more easily found later. A favourite is a link to a specific object. Its id and title are automatically created. The id and URL can be edited later.My favourites
If a member has at least one favourite, the actions box contains another link: My favourites. With this link the member has easy access to his/her favourites. The favourites can also be access via the folder Favourites in the member's folder.My Stuff
The link 'My Stuff' directs the browser to the uppermost folder of the current member. Here as well as in all subfolders, the member can add any object type, such as documents, news, links, etc. The existing objects are listed and can be viewed by clicking on their name.Actions When Viewing an Object
When viewing an object, the actions box contains certain actions that are the same for every object:View Edit Metadata Submit Status historyWhen an object was submitted it is pending until a reviewer either publishes or rejects the object. A published object can also be retracted when it is published or pending. All these statuses of an object are part of the staging process:
submitted pending published rejected retractedTherefore, an object needs more actions than listed above depending on its current status and/or if the current user is a reviewer:
Publish Retract Reject
View
The link 'View' shows the current object in the third view. The actions box shows the current status of the object below the its name.
***05FIG10.gif***
Figure 05.10. The third view of an object.
Edit
To change the object, for example its upload a new file if the current object is of the type File or change the lead-in of a News object, click on the 'Edit' link. The data that can be edited depend on the object's tpye.Metadata
The metadata is the title, the description, the subject and the format of an object. There is more metadata that can be edited by clicking on the link 'Edit all metadata' at the right top of the metadata edit form.
***05FIG11.gif***
Figure 05.11. The form to edit metadata.
Submit
Submitting an object is part of the staging process. If a member wants to publish an object so that it can be seen by other members of the portal, he/she has to submit it. In the submit page, the member can enter a comment concerning the object.
***05FIG12.gif***
Figure 05.12. Submitting an object.
Status history
The status history gives an overview of the object's different statuses, such as private, pending, published, etc. It also states the dates when the status changed and who changed it.
***05FIG13.gif***
Figure 05.13. The status history of an object.
If a comment was given, for example at the submission or publishing of an object, this comment is listed below the corresponding status change.
Publish
If the current object is pending and the current user is a reviewer, the actions box contains the link 'Publish'. If the reviewer looked at or read through an object, he/she may deem it fit for the public and publish it.After submitting the publish form, the object's status changes to published and it is now visible to all members of the portal.
Retract
A member might decide to retract a published or pending object for any reason, e.g. for revision. Clicking on the 'Retract' link leads to the retract form. The member may give a comment why he/she retracts the object and then change the object's status to private again by clicking the 'Retract this item' button.
***05FIG14.gif***
Figure 05.14. Retracting a published or submitted object.
Reject
A reviewer that decides not to publish a pending object but rather reject it, can do so by clicking on the 'Reject' link. The following page contains a form similar to the submit, publish and retract forms. Again a comment may be given and the status changed to private by clicking on the button 'Reject this item'.Folder contents
This link directs the browser to the content view of the current folder. This folder may be the member's folder, a subfolder of the member's folder or the CMF folder.Undo
The undo page lists transactions executed by the current member. Since a member only has permission to undo his/her own actions, the undo list does not contain any transactions executed by another member.
***05FIG15.gif***
Figure 05.15. Undo transactions.
The transactions can be undone by activating the checkbox to the left of the transaction(s) and then clicking the 'Undo' button.
Sometimes a transaction cannot be undone because later transactions have modified the object that the transaction concerns.
Pending review (number)
A reviewer has another link in the actions box. Whenever a member submits an object and it gets the status pending, the link 'Pending review (number)' appears in the reviewer's actions box. The number shown in brackets is the number of pending objects. By clicking on this link, the reviewer gets a list of the pending objects. He/she then needs to view the different objects and decide for each one whether it should be published or rejected.
***05FIG16.gif***
Figure 05.16. One object pending.
Customizing the Portal's Design and Layout
The default CMF instance has a certain design and layout. It has the Zope logo in the top left corner and the blue and white background color. But most times this is not what you want your portal to look like. You will want to put up a different logo and change the colors of the links, standard font, the background and so on to create your own portal.Everything you see on the portal is defined in a skin. That means, each color and every part of a page has a specific name and value which can be customized individually to create a different look. The new look then becomes a new skin. The default design and layout of the CMF is called the Basic skin.
Changing the Portal Skin
Every member can change the look of his view of the portal. The skin he/she chooses is saved as member data. Therefore, depending on which member is logged in and which skin that member chose, the look of the CMF differs.However, a member can only choose from a list of existing skins. He/she cannot create their own skins because creating a skin is done via the management screen and a normal portal member does not have access to Zope's management screen.
To choose a different skin, log on to the portal and go to the preferences page. At the bottom of the form, there is a select box called 'Skin'. The select box contains three elements: the three predefined skins � and yours after you created your own skins.
The Basics of Portal Skins
As already said above, a new skin is created via the Zope management screen. Access the management screen and change to the CMF instance you created.There you find an object 'portal_skins'. This is a portal tool that contains all the skins of this CMF instance. Now, change to the portal tool 'portal_skins'.
The eight folderish objects in this portal tool each contain part of what makes up the portal. You may recognize the names of two of the folderish objects: 'no_css' and 'nouvelle'. These two objects contain the necessary information that change the look of the CMF depending on whether 'No CSS' or 'Nouvelle' is chosen as skin. They do not contain every element of the CMF design and layout, i.e. the DTML Methods that create the CMF pages, but only the parts that actually make the changes. That is namely the Cascading Stylesheet and/or the stylesheet properties.
Change to the folderish object 'nouvelle'. You see two objects: nouvelle_stylesheet and stylesheet_properties (New Skin).
The stylesheet properties define certain parts of a CMF page, e.g. link, vlink, etc., and give each one a value, e.g. #CC0033. These properties are then used in the nouvelle_stylesheet as variables.
The stylesheet for the Basic skin can be found in the folderish object 'generic' in the portal tool 'portal_skin'. Here, however, you also find some of the DTML Methods that create the CMF pages. The rest of the DTML Methods are in the folderish objects 'content' and 'control' depending on their purpose. DTML Methods that are responsible for creating and presenting content, such as the form to create a News Item or to edit metadata, are combined in 'content'. The folderish object 'control' contains DTML Methods that help configure and maintain the CMF from a member's viewpoint.
Creating a New Portal Skin
The first thing you need to do is add a new folder to the portal tool 'portal_skin'. Change into the portal tool and add the folder 'MySkin'.
***05FIG17.gif***
Figure 05.17.
Adding the folder 'MySkin'.
Now you need to decide, what you want your skin to look like. If you just want to change the colors of links, background and so on, your new skin will be finished in just a few minutes. But if you wish to change the layout, you will need to change actual HTML pages and this may take a lot longer. For now, we will create a new skin that uses the same layout but different colors.
Changing Colors
As you know, there are three existing skins and that the stylesheet properties define the colors of a skin. This what we need to customize now. The easiest way to do this is using the stylesheet properties of one of the existing skins.Go to the 'nouvelle' folder in 'portal_skins'. Here you find the stylesheet_properties object that belongs to the 'Nouvelle' skin. Click on this object to see its contents. The object has only one tab: the Customize-tab. You see the various properties that are defined for the 'Nouvelle' skin � each with a name and a value.
***05FIG18.gif***
Figure 05.18. The object stylesheet_properties of the folder nouvelle.
At the top of the list of properties, there is a drop-down menu and a 'Customize' button. You will find the new folder 'MySkin' in this drop-down menu. That is why it is important to first add a new folder to 'portal_skins' before starting to create a new skin. 'MySkin' should already be selected in the menu � if not, choose it now and then click the 'Customize' button.
Clicking the button causes that a new folder with the name 'stylesheet_properties' is added to the folder that was selected from the drop-down menu, i.e. 'MySkin', and that it receives all the properties that the original 'stylesheet_properties' has.
***05FIG19.gif***
Figure 05.19. The customizable stylesheet_properties object.
Now you are in the folder 'stylesheet_properties' in your skin folder 'MySkin'. The list of properties has become a form where the value fields can be edited.
Change the values of 'primary_accent_color' and 'secondary_accent_color' to #00FFCC. Then save the changes by clicking the button 'Save changes' at the bottom of the form.
***05FIG20.gif***
Figure 05.20. 'MySkin' with the stylesheet_properties folder.
Whenever you wish to change other colors of 'MySkin', go to the folder 'stylesheet_properties' in the 'MySkin' folder and click on the 'Properties' tab to get the properties form.
But changing the stylesheet properties is not enough to finish the new skin. You need to tell the CMF that there is a new skin that should be available to the memebers. This is done in the 'Properties' view of 'portal_skins'. Go to 'portal_skins' and click on the 'Properties' tab.
***05FIG21.gif***
Figure 05.21. The Properties view of portal_skins.
You see the 'Properties' form containing the properties
Skin selections Default skin REQUEST variable name Skin flexibilityTo make the new skin available in the CMF, add it to the 'Skin selections'. Fill out the fields blow the existing skins as follows:
Name: My Skin Layers: MySkin, custom, nouvelle, content, generic, controlThe layers, i.e. the folders that are to be searched for any specific object, have to be given in a certain order. The new skin has be first in line because any object that needs to be found should first be looked up in the 'MySkin' folder. As you know, there are more than one object called 'stylesheet_properties' � each skin has one. But if a member has chosen 'MySkin' as his preference, Zope should find the 'stylesheet_properties' object of 'MySkin' and not the one in 'nouvelle' or 'generic'.
The folder 'nouvelle' has to be in this list because one property ('select_stylesheet_id') in 'stylesheet_properties' refers to the object 'nouvelle_stylesheet'. Zope will throw an error if you do not include 'nouvelle' in the list of layers because it does not know where to find 'nouvelle_stylesheet'.
You could also customize 'nouvelle_stylesheet' so that a copy of it is transferred to the folder 'MySkin'. Then you would not have to include 'nouvelle' in the layers list. Either way works.
Now, click the 'Add' button, and the skin will be added to the list of skins.
***05FIG22.gif***
Figure 05.22. The new skin has been added.
If you now enter the 'Preferences' page of the CMF, you will see that 'MySkin' is included in the drop-down menu 'Skin'.
***05FIG23.gif***
Figure 05.23.
The preference page with the new skin in the skins menu.
Change the skin to 'MySkin' and save the preferences by clicking 'Change'. The following figure shows what a difference changing just two property values can make.
***05FIG24.gif***
Figure 05.24. The portal's new look due to the skin MySkin.
Changing Layout
Creating a skin that not only has different colors but also changes the layout of the CMF pages, is a bit more complex. It requires the same steps as are shown above but now you will also need to change DTML Methods. The hardest part is probably to find the correct DTML Method that is responsible for the part of the CMF which you want to change.As said before, the folders in 'portal_skins' contain all the DMTL Methods that are needed for the CMF pages. See "The portal_skins Content" for where to find what part of the CMF pages.
Let's move the news box below the actions box so that it appears on all CMF pages, just like the actions box does. For this we need to change two DTML Methods:
standard_html_header index_htmlBoth DTML Methods are in the 'generic' folder.
Since all elements of the CMF pages are practically split up in small parts, i.e. they are in different DTML Methods, it is very easy to put the news box on the left.
Go to the 'generic' folder and click on 'index_html'. Customize the DTML Method by choosing 'MySkin' from the drop-down menu and clicking the 'Customize' button.
Do the same with the 'standard_html_header'. Now look at the the line 13 in 'index_html' and line 26 in 'standard_html_header'.
Listing 05.01. index_html in the folder 'generic'.
<dtml-var standard_html_header>
<dtml-with portal_properties>
<table cellpadding="0" cellspacing="0" width="100%">
<tr>
<td valign="top" width="80%">
<h1> Welcome to &dtml-title; < /h1>
<dl>
<dt> Overview < /dt>
<dd> < dtml-var description> < /dd>
</dl>
</td>
<td valign="top" width="20%">
<dtml-var news_box>
</td>
</tr>
</table>
</dtml-with>
<dtml-var standard_html_footer>
In line 13 you see the < dtml> -command < dtml-var news_box> . As you know, this calls an object or property called news_box. This is the first part that needs to be changed.
Listing 05.02. standard_html_header in the folder generic.
<dtml-if "_.hasattr(this(),'isEffective') and not isEffective( ZopeTime())">
<dtml-unless "portal_membership.checkPermission('Request review',this()) or portal_membership.checkPermission('Review portal content',this())">
<dtml-var "RESPONSE.unauthorized()">
</dtml-unless>
</dtml-if>
<html>
<head>
<title> < dtml-with portal_properties> &dtml-title;< /dtml-with> < dtml-if name="Title"> : &dtml-Title;< /dtml-if>
</title>
<dtml-var css_inline_or_link>
</head>
<body>
<dtml-var standard_top_bar>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<!-- Vertical whitespace -->
<td colspan="4"> < br /> < /td>
</tr>
<tr valign="top">
<td class="SideBar" width="15%" align="left" valign="top">
<dtml-comment> Menu is now in top bar.
<dtml-var menu> < br />
</dtml-comment>
<dtml-var actions_box>
</td>
<!-- Horizontal whitespace -->
<td width="1%"> < /td>
<td class="Desktop" colspan="2" width="84%" valign="top">
<dtml-if "not portal_membership.isAnonymousUser() and
not _.hasattr(portal_membership.getAuthenticatedMember(),
'getMemberId')">
<div class="AuthWarning">
<table>
<tr class="Host">
<td> Warning! < /td>
<tr>
<td>
You are presently logged in as a user from outside
this portal. Many parts of the portal will not work!
You may have to shut down and relaunch your browser to
log out, depending on how you originally logged in.
>
</td>
</tr>
</table>
</div>
</dtml-if>
<dtml-if portal_status_message>
<p class="DesktopStatusBar"> &dtml-portal_status_message;< /p>
</dtml-if>
<dtml-if localHeader>
<dtml-var localHeader>
</dtml-if>
In line 26 is the < dtml> -command < dtml-var actions_box> . Now enter the line
<dtml-var news_box>
between lines 26 and 27. In 'index_html' delete line 13 so that the news box does not appear on both sides of the homepage. That's it! If a member now uses the skin 'MySkin' the news box will appear on the left side below the actions box in all CMF pages.
Using Scripts in Skins
There is another way to customize a skin. You can use a Python script to create Python commands that for example calculate the background color from the member's name. As you already know, the background color is defined as a property for the skin's stylesheet. It is called 'bg_color'. Since Zope first looks for this property in 'stylesheet_property', you have to delete it there before you can use a Python script with the same name.So, go to the 'stylesheet_property' object in 'MySkin' and click on the 'Properties' tab. Now activate the checkbox infront of the property 'bg_color' and click on the button 'Delete'.
Go back to the folder 'MySkin' and select the item 'Script (Python)' from the drop-down menu. Add the script with the id 'bg_color'.
In order to have the background color calculated from the name of the currently logged in member, we need to give the member's name to the Python script as a parameter. Click on the Python script 'bg_color' and enter 'name' in the field for the parameters.
***05FIG25.gif***
Figure 05.25. The Python script bg_color.
Enter the following code in the textarea of the Python script:
Listing 05.03. Python script 'bg_color'.
bgcolor='' for i in name: bgcolor = bgcolor + str(ord(i) - 96) if len(name) < 6: for j in range(7-len(name)): bgcolor = bgcolor + 'F' bgcolor = bgcolor[0:6] bgcolor = '#' + bgcolor return bgcolorLine 1 initializes the variable bgcolor so that it can be used in line 3. The loop in lines 2 and 3 goes through the member's name and takes each letter. With ord(i), we get the ASCII number for the respective letter. We take away 96 because 'a' has the ASCII number 97 and all the other letters in the alphabet come after that. By taking away 96, we make sure do not get three-digit numbers.
Since an HTML color has six digits, we need to catch the possibility that a members name has less than six letters and that therefore we might not have enough digits after the loop in lines 2 and 3. That is why lines 5 and 6 are executed if the member's name is shorter than six letters. For every digit that is missing from a six-digit number, we add an 'F' (lines 5 and 6).
Then, we take the first six digits (line 7) and put a number sign (#) infront of them (line 8). The HTML color is completed and can be returned (line 9).
Writing this script, however, is not enough. It needs to be called from somewhere and the member's name needs to be handed over. This is done in the object that contains the Cascading Stylesheet. So, we have to customize the 'nouvelle_stylesheet' because that is the one that is used in 'stylesheet_properties'. Customize the stylesheet and replace
&dtml-bg_color;
with
< dtml-var "bg_color(_.str(portal_membership.getAuthenticatedMember().getUserName()))">
everywhere in the stylesheet. Make sure you have replaced all &dtml-bg_color; or you will get an error when you try to view any CMF page.
The 'portal_skins' Content
The following pages will give you an overview of the different folders in 'portal_skins'. They will help you find the parts that need to be changed for a new skin.The Folder 'Images'
As the name says, this folder contains images. There are six default images in there:UpFolder_icon.gif go.gif logo.jpg logo.png spacer.gif tinyzope.jpgWhen you use your own images, you can either store them in this folder or in the folder of the your skin. But it may be better to put images in the 'Images' folder because if you use an image in different skins and then delete one skin, you may accidentally delete an images that is needed in another skin.
The Folder 'content'
The folder 'content' contains DTML Methods that produce CMF pages that deal with creating and maintaing content. Those pages for example are edit pages or forms to add new objects. It also contains the icons for the different objects, such as documents or folders.content_publish_form content_reject_form content_retract_form content_status_history content_status_modify content_submit_form document_edit document_edit_form document_icon.gif document_view favorite_view file_edit file_edit_form file_icon.gif file_view folder_edit folder_edit_form folder_icon.gif full_metadata_edit_form image_edit image_edit_form image_icon.gif image_view link_edit link_edit_form link_icon.gif link_view metadata_edit metadata_edit_form newsitem_edit newsitem_edit_form newsitem_icon.gif newsitem_view
The Folder 'control'
This folder contains the DTML Methods that are responsible for "controlling" portal contents, i.e. they let you cut, copy, paste and delete content. They also let you register, personalize and log out.addtoFavorites change_password content_status_modify finish_portal_construction folder_copy folder_cut folder_delete folder_paste folder_rename logout mail_password personalize reconfig register search_debug undo
The Folder 'custom'
The folder 'custom' is empty by default. It can be used to customize the 'Basic' skin. You can also customize other skins but then you need to change the order of the layers in the 'Properties' view of 'portal_skins'.The Folder 'generic'
The folder 'generic' contains all the other DTML Methods for the CMF pages as well as the 'stylesheet_properties' and the 'default_stylesheet' used by the 'Basic' skin.actions_box clearCookie content_byline content_publish_form content_reject_form content_retract_form content_status_history content_submit_form css_inline_or_link default_stylesheet discussion_reply_form discussion_reply_preview discussion_thread_view folder_add folder_contents folder_factories folder_filter_form folder_rename_form index_html join_form logged_in logged_out login_form mail_password_form mail_password_template menu metadata_help news_box password_form personalize_form recent_news reconfig_form registered registered_notify roster search search_form showThreads simple_metadata standard_html_footer standard_html_header standard_top_bar stylesheet_properties (Classic PTK Style) undo_form viewThreadsAtBottom
The Folder 'no_css'
This folder contains the 'stylesheet_properties' object for the skin that uses no Cascading Stylesheet (CSS). It is the only object in this folder because it is the only object necessary to overwrite the CSS of the 'Basic' skin in the folder 'generic'.The Folder 'nouvelle'
This folder contains the 'stylesheet_properties' and the 'nouvelle_stylesheet' for the 'Nouvelle' skin. The 'nouvelle_stylesheet' is necessary because the 'Nouvelle' skin assigns the properties differently to the CSS.Example: AchieversInternational Skin
In this section, we will create the AchieversInternational skin. Figure 05.26. shows what this skin will look like.
***05FIG26.gif***
Figure 05.26. The CMF with the AchieversInternational skin. To create this skin, we need a new image: the Achievers International logo. All the other changes can be made using the existing DTML Methods. The DTML Methods that need to be customized are:
actions_box news_box nouvelle_stylesheet standard_top_barThe skin is based on the Nouvelle skin, therefore Nouvelle's stylesheet_properties needs to be modified as well.
Let's start with the new folder for our skin. Create a folder called AchieversInternational in 'portal_skins'. Now, customize Nouvelle's stylesheet_properties according to table 05.01.
Table 05.01. The AchieversInternational stylesheet_properties
Property name | Property value |
alink_color | lightgrey |
base_font_color | #000000 |
base_font_size | 8pt |
bg_color | #FFFFFF |
guest_actions_color | #FFEEEE |
guest_actions_link_color | #660000 |
highlight_color | #888888 |
highlight_font_color | #000000 |
hover_color | lightgrey |
link_color | #009966 |
primary_accent_alink_color | #009966 |
primary_accent_color | #003366 |
primary_accent_font_color | #009966 |
primary_accent_link_color | #009966 |
primary_accent_text_color | #009966 |
primary_accent_vlink_color | #009966 |
primary_font_family | Arial, Verdana, Helvetica, sans-serif |
secondary_accent_alink_color | #009966 |
secondary_accent_color | #666666 |
secondary_accent_font_color | #000000 |
secondary_accent_link_color | #FFFFFF |
secondary_accent_vlink_color | #FFFFFF |
secondary_font_family | Verdana, Arial, Helvetica, sans-serif |
select_stylesheet_id | nouvelle_stylesheet |
title | Achievers International Style |
vlink_color | #009966 |
Now, we can customize the object nouvelle_stylesheet. Only two part of the stylesheet need to be modified: the table.ActionBox and the tr.NewsItemRow td. Both the ActionBox table and a cell within the NewsItemRow will get a new background color. Change these two parts in nouvelle_sheet in accordance to listing 05.04.
Listing 05.04. Modified parts of nouvelle_stylesheet.
.... table.ActionBox { font-family: &dtml-primary_font_family;;< background-color: lightgrey; } .... tr.NewsItemRow td { background-color: #cdcdcd; font-size: 70%; }At this point we can upload the new image we need for the skin: a logo, that will replace the Zope logo in the upper left-hand corner of the portal pages. Use your own logo, which should be about 60x65 pixel in size.
To upload the image, go to the skin folder AchieversInternational, add an Image object and name it portal_logo.
The next step is to modify the necessary DTML Methods. Use the listings 05.05 to 05.07 to customize the DTML Methods actions_box, news_box and standard_top_bar.
Listing 05.05. The modified DTML Method actions_box.
<dtml-let isAnon="portal_membership.isAnonymousUser()"
AuthClass="isAnon and 'GuestActions' or 'MemberActions'"
uname="isAnon and 'Guest'
or portal_membership.getAuthenticatedMember().getUserName()"
obj="this()"
actions="portal_actions.listFilteredActionsFor(obj)"
user_actions="actions['user']"
folder_actions="actions['folder']"
object_actions="actions['object']"
global_actions="actions['global']">
<table class="ActionBox" width="100%" cellpadding="4">
<tr class="&dtml-AuthClass;">
<td bgcolor="#009966">
<img src="user_icon" align="left" alt="User">
<dtml-var uname>
</td>
</tr>
<tr class="&dtml-AuthClass;">
<td bgcolor="#003366">
<dtml-in user_actions mapping>
<a href="&dtml-url;"> < dtml-var name> < /a> < br>
</dtml-in>
</td>
</tr>
<dtml-if folder_actions>
<tr class="&dtml-AuthClass;">
<td bgcolor="#003366"> < dtml-in folder_actions mapping>
<a href="&dtml-url;"> < dtml-var name> < /a> < br>
</dtml-in>
</td>
</tr>
</dtml-if>
<dtml-if object_actions>
<tr class="&dtml-AuthClass;">
<td bgcolor="#003366">
<font color="lightgrey">
<dtml-let icon="obj.icon"
mt="obj.meta_type"
objID="obj.id">
<img src="&dtml-portal_url;/&dtml-icon;" align="left"
alt="&dtml-meta_type;">
&dtml-objID;
</dtml-let>
</td>
</tr>
<tr class="&dtml-AuthClass;">
<td bgcolor="#003366">
<font color="lightgrey">
<dtml-if expr="_.hasattr(obj, 'review_state')">
Status:< dtml-var "obj.review_state"> < br>
</dtml-if>
<dtml-in object_actions mapping>
<a href="&dtml-url;"> < dtml-var name> < /a> < br>
</dtml-in>
</td>
</tr>
</dtml-if>
<dtml-if global_actions>
<tr class="&dtml-AuthClass;">
<td bgcolor="#003366">
<dtml-in global_actions mapping>
<a href="< dtml-var url> "> < dtml-var name> < /a> < br>
</dtml-in>
</td>
</tr>
</dtml-if>
</table>
</dtml-let>
The changes made to the DTML Method actions_box are the background colors in the table cells and some textcolors within the cells. Note that the table cells do not all have the same background color. Also, a cellpadding of 4 has been added to the table.
Listing 05.06. The modified DTML Method news_box.
<table class="NewsItems" cellspacing="0" cellpadding="4" border="0" width="100%">
<tr> < td valign="top" class="NewsTitle" width="100%">
<b> News< /b>
</td>
</tr>
<dtml-in "portal_catalog.searchResults( meta_type='News Item'
, sort_on='Date'
, sort_order='reverse'
, review_state='published'
)" size="10">
<tr class="NewsItemRow">
<td valign="top">
<a href="< dtml-var "portal_catalog.getpath( data_record_id_ )"> "> &dtml-Title; < /a> < br>
<dtml-var Date>
</td>
</tr>
<dtml-else>
<tr class="NewsItemRow">
<td valign="top">
No news is no news.
</td>
</tr>
</dtml-in>
<tr class="NewsItemRow">
<td>
<a href="&dtml.url-recent_news;"> More...< /a>
</td>
</tr>
</table>
Again, a cellpadding of 4 was added to the table in the DTML Method news_box. Also, the first table cell was deleted.
Listing 05.07. The modified DTML Method standard_top_bar.
<!-- Top bar -->
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr> < td colspan="3" witdth="100%">
<!-- hack around netscape 4.x to ensure top table is solid black -->
<table class="Masthead" cellspacing="0" cellpadding="4" border="0" width="100%">
<tr class="Masthead">
<td class="PortalLogo" align="left" valign="top" width="1%"> < a
href="&dtml-portal_url;"> < img src="portal_logo" width="60" height="65"
alt="Achievers International Logo" border="0"> < /a> < /td>
<td class="PortalTitle" width="29%" align="left" valign="center">
<h1> < dtml-with portal_properties> &dtml-title;< /dtml-with> < dtml-if
name="Title"> : &dtml-Title;< /dtml-if> < /h1>
</td>
<td class="NavBar" align="right" valign="bottom" width="70%" wrap="no">
<form action="&dtml-portal_url;/search">
<a href="&dtml-portal_url;"> home< /a>
<a href="&dtml-portal_url;/roster"> members< /a>
<a href="&dtml-portal_url;/recent_news"> news< /a>
<a href="&dtml-portal_url;/search_form"> search< /a>
<input name="SearchableText" size="16">
<input border="0" type="image" name="go" src="Images/go.gif">
</form>
</td>
</tr>
</table>
</td> < /tr> < /table>
In the DTML Method standard_top_bar, we have changed the image source for the logo (lines 9 and 10) and added the cellpadding of 4.
The last step is to add the skin to the Properties view of portal_skin. Now, the member of your portal can choose to use the AchieversInternational skin.
The CMF Types
What is a Type?
A CMF type is an object that contains certain data and metadata. Each type has a set of properties and actions.
The properties define the title, description, metatype, icon and some information the CMF needs to add an object of this type. You can also define whether member can reply to an object, i.e. whether the object is allowed to be discussed.
The type's actions define which DTML Method or DTML Document is to be called to be used as an Add or Edit page.
The standard CMF types are:
News Item Document File Image Link Folder Favourite
The Properties View of a Type
The types are defined in the portal tool 'portal_types'. Clicking on a type calls up the type's Properties view.
***05FIG27.gif***
Figure 05.27.
Properties view of the Document type.
Giving a title for the type is voluntary but you should give a description. The description appears below the type's name on the page where a member can choose which type of object he/she wants to add to his/her folder.
The next property is the metatype. The metatype is important for filtering objects when a member only wants to have certain types listed in his/her folder.
In the Icon field on the Properties view, you see the name of the image that appears in front of an object of this type.
Product name and Factory method in product define where Zope has to look for the method that actually creates the new object in the member's folder. The factory method is a Python method within a Zope product, e.g. the method addDocument() in the CMFDefault product.
On the Properties view, you also find a checkbox 'Allow Discussion?'. If this checkbox is activated, members can reply to an object of this type by clicking the action reply that appears in the actions box. The links to replies to an object are then shown at the bottom of the object.
The Actions View of a Type
In the Actions view of a type you define the different views that are necessary to add and edit an object of this type. However, you do not add the DTML Methods here that create the views but you state what the DTML Methods are called and what permission a member must have in order to be able to see the respective view.
***05FIG28.gif***
Figure 05.28. The Actions view with defined actions.
Each action contains of a name, id, action, permission and category. There need to be at least three actions for a type:
View Edit MetadataThe View action is needed so that a member can see the third view of an object and the Edit action needs to be defined so that an object can be created and edited. The Metadata view is also necessary for creating and editing an object but it is for editing the objects metadata.
The name of an action appears as a link in the actions box in the CMF when an object of the respective type is viewed. In the action field of an action you find the name of the DTML Method that is called when a member clicks the respective link for this action.
Creating a New Type
There are a couple of ways to create a new type depending on what kind of type you want to create. If you want to create a type that is only slightly different than one that already exists, e.g. if you want to change the name and representation of a type, you base your new type on the existing one. This is what we will do first. Later, we will explain how to add default values for a type and how to create a new product as a type by using a ZClass.Using an Existing Type to Create a New One
In this section, we will create a new portal type called CV which will be based on the Document type. The CV type will have its own icon and its representation will be slightly different than that of the Document type.Adding the New Type
The first step in creating a new type this way is to add a 'Factory-based Type Information' object in the type folder portal_types. Select this object from the drop-down-menu. This calls up the add form for the object. Enter the id CV and choose CMFDefault: Document from the drop-down-menu.
***05FIG29.gif***
Figure 05.29. Adding the new CV type.
Editing the Types Properties
Now we change the properties so that this new type does not have the same description, metatype and icon as the Document type which it is based on.Enter the following as a description for the CV type which will appear below the type's name in the list of types a member can choose from when creating a new object:
CVs contain text that can be formatted using Structured Text.
The type's metatype shall be CV, therefore, type CV into the Metatype field. In the next field, Icon, we need to give the name of the icon that shall appear infront of on object of the CV type. You can either use an existing icon or create a new one with a program like Adobe Photoshop for example. Since we want CV objects to have a different icon than the other types, we created a simple icon that looks like this:
***05FIG30.gif***
Figure 05.30. The CV icon. Enter cv_icon.jpg in the Icon field since this is what we will call the icon when we add the respective image object to Zope. The fields Product name and Factory method in product need to stay the way they are but the field Initial view name has to be changed. Enter cv_metadata_edit_form in this field now and save the changes. The DTML Method cv_metadata_edit_form does not exist yet but we will create it after editing the type's actions.
Modifying the CV Type's Actions
Changing the actions to fit our new type does not require much editing. Because we used the Document type as a basis, the CV type already has the usual three actions defined for it:View Edit MetadataThe only fields that need changing are the Action fields since they define which DTML Method to call when the respective action link is clicked in the object's action box. To fit our type, change the action fields as follows: Table 05.02. The old and new values of the Action fields
Old value | New value |
document_view | cv_view |
document_edit_form | cv_edit_form |
metadata_edit_form | cv_metadata_edit_form |
Save the changes by clicking the Save button.
Customizing the DTML Methods
Before we can use the CV type, we need to create the DTML Methods we just defined would be used to add and edit a CV object. We do this by customizing the existing DTML Methodsdocument_view document_edit document_edit_form full_metadata_edit_form metadata_edit metadata_edit_formand renaming them as seen in table 05.03.
Table 05.03. Original and new names of DTML Methods
Original name | New name |
document_view | cv_view |
document_edit | cv_edit |
document_edit_form | cv_edit_form |
full_metadata_edit_form | full_cv_metadata_edit_form |
metadata_edit | cv_metadata_edit |
metadata_edit_form | cv_metadata_edit_form |
- Click on the DTML Method
- Select 'custom' from the drop-down-menu
- Click the Customize button
- Go to the custom folder
- Activate the checkbox infront of the DTML Method
- Click the Rename button
- Rename the DTML Method in accordance with table 05.03
***05FIG31.gif***
Figure 05.31. An object of the CV type.
In the management screen edit the DTML Method cv_view by clicking on it. Replace the existing code with the code from listing 05.08.
Listing 05.08. The DTML Method cv_view.
<dtml-var standard_html_header>
<div class="Desktop">
<div class="CV">
<b> CV:< /b> < dtml-var title_or_id>
<hr>
<dtml-var cooked_text> < br>
<hr>
<br>
<dtml-var content_byline>
<div class="Discussion">
<dtml-var viewThreadsAtBottom>
</div>
</div>
14:</div>
15:<dtml-var standard_html_footer>
The changes are not that complicated but the difference they make in the layout are considerable. Listing 05.08. changes the order in which the object's content and the creation date and author is shown (lines 6 and 9). It also adds the title � or id, depending on whether the object has title or not � in line 4. The title, content and date of creation are divided by two horizontal lines (lines 5 and 7).
Now we need to change the DTML Methode cv_edit.
Listing 05.09. The DTML Method cv_edit.
<dtml-call expr="edit(REQUEST['text_format'],
REQUEST['text'], REQUEST.get('file', ''))">
<dtml-let portal_status_message="'CV changed.'">
<dtml-return cv_edit_form>
</dtml-let>
The only change in this DTML Method occurs in line 4. The name of the returned DTML Method has to be changed to cv_edit_form according to the modified document_edit_form. Save the change and go to the DTML Method cv_edit_form.
Listing 05.10. shows the DTML Method cv_edit_form which is called by cv_edit.
Listing 05.10. The DTML Method cv_edit_form.
<dtml-var standard_html_header>
<div class="Desktop">
<dtml-if message>
<p> &dtml-message;< /p>
<hr>
</dtml-if>
<div class="CV">
<h2> Edit &dtml-id;< /h2>
<form action="cv_edit" method="post" enctype="multipart/form-data">
<table class="FormLayout">
<tr>
<th>
Title
</th>
<td>
<dtml-var Title>
</td>
</tr>
<tr>
<th>
Introductory Self-Description
</th>
<td>
<dtml-var description>
</td>
</tr>
<tr>
<th>
Format
</th>
<td>
<input type="radio" name="text_format" value="structured-text"
<dtml-if "text_format=='structured-text'"> checked< /dtml-if>
id="cb_structuredtext" />
<label for="cb_structuredtext"> structured-text< /label>
<input type="radio" name="text_format" value="html"
<dtml-if "text_format=='html'"> checked< /dtml-if>
id="cb_html" />
<label for="cb_html"> html< /label>
</td>
</tr>
<tr>
<th> Upload < /th>
<td>
<input type="file" name="file" size="25">
</td>
</tr>
<tr>
<th class="TextField"> Edit CV< /th>
<td class="TextField">
<textarea name="text:text" rows="20" cols="80"> < dtml-var text html_quote> < /textarea>
</td>
</tr>
<tr>
<td> < br> < /td>
<td>
<input type="submit" value=" Change ">
</td>
</tr>
</table>
</form>
</div>
</div>
In the DTML Method cv_edit_form, we need to change the action of the form (line 9) to cv_edit so that the correct DTML Method is called that commits the changes to the CV object. We also change two of the forms field titles: Description is changed to Introductory Self-Description (line21) and Edit is changed to Edit CV (line 49).
Next is the DTML Method cv_metadata_edit which needs two changes:
The status message that tells the member that the metadata of the CV object was successfully changed (line13).
The call that returns the next view has to be changed to cv_view (line 17).
Listing 05.11. The DTML Method cv_metadata_edit.
<dtml-call expr="editMetadata(
title=REQUEST.get('title', ''),
subject=REQUEST.get('subject', ()),
description=REQUEST.get('description', ''),
contributors=REQUEST.get('contributors', ()),
effective_date=REQUEST.get('effective_date', _.None),
expiration_date=REQUEST.get('expiration_date', _.None),
format=REQUEST.get('format', 'text/html'),
language=REQUEST.get('language', 'en-US'),
rights=REQUEST.get('rights', ''))">
<dtml-if expr="REQUEST.get('change_and_edit', 0)">
<dtml-let method="restrictedTraverse(getTypeInfo().getActionById('edit'))"
portal_status_message="'CV Metadata changed.'">
<dtml-return method>
</dtml-let>
<dtml-else>
<dtml-return cv_view>
</dtml-if>
The next two listing (05.12 and 05.13) show the modified edit forms for the metadata. There are two listing since a member can either edit a short version of the metadata or the full version.
Listing 05.12. The DTML Method cv_metadata_edit_form.
<dtml-var standard_html_header>
<div class="Desktop">
<dtml-if message>
<p> &dtml-message;< /p>
<hr>
</dtml-if>
<div class="Metadata">
<h2> Resource Metadata < /h2>
<form action="cv_metadata_edit" method="post">
<table class="FormLayout">
<tr valign="top">
<th align="right"> Identifier
</th>
<td>
<dtml-var Identifier>
</td>
<td colspan="2" align="right">
<a href="full_cv_metadata_edit_form"> Edit all CV metadata < /a>
</td>
</tr>
<tr valign="top">
<th align="right"> Title
</th>
<td colspan="3">
<input type="text" name="title" value="&dtml-Title;" size="65">
</td>
</tr>
<tr valign="top">
<th align="right"> Introductory Self-Description
</th>
<td colspan="3">
<textarea name="description:text" rows="5" cols="65"> &dtml-Description;< /textarea>
</td>
</tr>
<tr valign="top">
<th align="right"> Subject
</th>
<td>
<textarea name="subject:lines" rows="5" cols="30"> < dtml-in Subject> < dtml-var sequence-item>
</dtml-in> < /textarea>
</td>
<th align="right"> Format
</th>
<td> < input type="text" name="format" value="&dtml-Format;">
<br> < input type="submit" name="change_and_edit" value=" Change & Edit ">
<br> < input type="submit" name="change_and_view" value=" Change & View ">
</td>
</tr>
</table>
</form>
</div>
</div>
<dtml-var standard_html_footer>
There are three lines in the DTML Method cv_metadata_edit_form that have to be changed to fit the CV type.
Line 9 � The form action has to be changed to cv_metadata_edit to call the correct DTML Method. Line 18 � The link to the full metadata edit form has to be modified for the new DTML Method full_cv_metadata_edit_form. Line 32 � The Description field is now called Introductory Self-DescriptionListing 05.13. The DTML Method full_cv_metadata_edit_form.
<dtml-var standard_html_header>
<div class="Desktop">
<dtml-if message>
<p> &dtml-message;< /p>
<hr>
</dtml-if>
<div class="Metadata">
<h2> Resource Metadata < /h2>
<dtml-let effectiveString="effective_date and effective_date.ISO() or 'None'"
expirationString="expiration_date and expiration_date.ISO() or 'None'">
< form action="cv_metadata_edit" method="post">
<table class="FormLayout">
<tr valign="top">
<th align="right"> Identifier
</th>
<td colspan="3"> < dtml-var Identifier>
</td>
</tr>
<tr valign="top">
<th align="right"> Title
</th>
<td colspan="3">
<input type="text"
name="title"
value="&dtml-Title;"
size="65">
</td>
</tr>
<tr valign="top">
<th align="right"> Introductory Self-Description
</th>
<td colspan="3">
<textarea name="description:text" rows="5" cols="65"> &dtml-Description;< /textarea>
</td>
</tr>
<tr valign="top">
<th align="right"> Subject
</th>
<td>
<textarea name="subject:lines" rows="5" cols="30"> < dtml-in Subject> < dtml-var
sequence-item>
</dtml-in> < /textarea>
</td>
<th align="right"> Contributors
</th>
<td>
<textarea name="contributors:lines" rows="5"
cols="30"> < dtml-in Contributors> < dtml-var sequence-item>
</dtml-in> < /textarea>
</td>
</tr>
<tr valign="top">
<th align="right"> Creation Date
</th>
<td> < dtml-var CreationDate>
</td>
<th align="right"> Last Modified Date
</th>
<td> < dtml-var ModificationDate>
</td>
</tr>
<tr valign="top">
<th align="right"> Effective Date
</th>
<td> < input type="text" name="effective_date"
value="&dtml-effectiveString;">
</td>
<th align="right"> Expiration Date
</th>
<td> < input type="text" name="expiration_date"
value="&dtml-expirationString;">
</td>
</tr>
<tr valign="top">
<th align="right"> Format
</th>
<td> < input type="text" name="format" value="&dtml-Format;">
</td>
</tr>
<tr valign="top">
<th align="right"> Language
</th>
<td> < input type="text" name="language" value="&dtml-Language;">
</td>
</tr>
<tr valign="top">
<th align="right"> Rights
</th>
<td> < input type="text" name="rights" value="&dtml-Rights;">
</td>
</tr>
<tr valign="top">
<td> < br> < /td>
<td>
<input type="submit" value=" Change ">
</td>
</tr>
</table>
</form>
</dtml-let>
</div>
</div>
<dtml-var standard_html_footer>
The two changes in the DTML Method full_cv_metadata_edit_form occur in line 12 where the action again has to be changed to fit the new DTML Methods, and in line 31 where the description field name needs modification.
Now, the new type is ready to be used by the portal's members. They can add and edit objects of this type any of the default CMF types. (e) Creating a Type with ZClasses < this part needs further study>
Future of CMF
If you visit cmf.zope.org/docyou will find a series of documents such as the �Project Charter/Vision Statement� which describe the CMF and the design aspects behind its construction. Additionally, you will also find documents discussing or announcing several future features.
One of these documents �Thoughts on different Portal designs and the CMF� describe goals such as �ParserHandlers� which would parse incoming files such as Word or PDF documents and extract the content and relevant metadata for indexing with the Zope�s built in ZCatalog search index.
Especially for long texts or visually appealing documents such as product brochures this is a vital feature since the ZCatalog would otherwise be blind to some of the most interesting resources available via the Portal.
For some non-technical working staying within the Windows/Office world they are so accustomed to may be ideal. For them their user directory on the Zope Server would show up simply as regular (web) folder in their Windows Explorer.
This is possible because Zope works with Internet standards such as FTP and WebDAV which is gaining popularity and can already be used with recent versions of Internet Explorer, Mac OS X finder, Eazel, and Adobe GoLive 5. Using WebDAV can simply drag-and-drop their files with future versions of CMF taking care of the actual indexing � thereby making it so much easier to share information with people on the Internet or their Intranet.