ZopeMag's mascot the ZOPE fish


Article Finder
People
Issue 6 - Revision 8  /   January 18, 2003 


 
  ZopeMag Links:
Latest Issue
About the Fish
Issue 10
Issue 09
Issue 08
Issue 07
Issue 06
Issue 05
Issue 04
Issue 03
Issue 02
Issue 01
 
 
Downloads
     
  Letter from the Editor:
   Issue 6

Interviews:
Each issue we interview important people in the Zope world.

  Alan Runyan

Articles:
Throughout the quarter we cover topics of interest to Zope developers, designers, and users.

  Intro to Archetypes

  Customized User Folders Revisited

  Plone Workflows

  Enriching Zope UIs With XML

Product Review:
Too many Products, too little time? ZopeMag keeps you up-to-date which Zope Products are worthwhile downloading.

  Formulator
  ZStyleSheets


Guides:
This quarter we bring you a new miniGuide and our first SuperGuide. These Guides give you the background knowledge you need to mastering Zope.

  miniGuide to importing a Website
  SuperGuide for Zope Newbies.
 
 
Downloads
     
  URLs / Download
Products we talk about in this issues Articles and Reviews

  Formulator
  ZSQL Catalog
     

Illustration by Lia Avant
tutorial
Enriching Zope UIs With XML

Enriching Zope UIs With XML
- Step-by-Step
- - - - - - - - - - - -

By Paul Everitt  | January 2, 2003



Overview

Sophisticated Web interfaces, such as content management tools, require that developers pay more attention to usability questions. Demands are also increased on server performance.

In this article we look at increasing usability and improving server performance by moving interaction from the server to the browser through XML and XSLT. This hands-on tutorial will show how an XML interface can be built for Zope that runs in IE and Mozilla, with discussion of the impact this technique can have on the development process itself.

Topics covered include:

  • Background on the motivations and general approach
  • A simple file-based example of XML and XSL in Web browsers
  • A dynamic version of the simple version, running in Zope
Background

Average Zope developers are faced with a number of template languages. Two in Zope, many more in Python, and multiples more in all the platforms they need to develop in.

At the same time, the component architecture that a template is applied to presents its challenges as well. In Zope, there are several: Zope 2, CMF, and Zope 3, not to mention Plone, Silva, and CPS. While these all have similarities, they also have more than enough differences to introduce a challenge for new developers.

In the industry, though, XML has gained traction as the "model" in application servers and content management system architectures. Primarily this means the XML Infoset. This growth in mindshare isn't just on the server side: both IE and Mozilla boast significant and useful XML capabilities, especially for creating targetted and highly-responsive user interfaces.

Against this background, this article describes techniques and projects that wed these ideas to development for Zope. The article shows how to create an XML-based interface for Zope applications, what its benefits and drawbacks are, as well as the impact on a consulting practice.

The Approach, In a Nutshell

With this XML approach, a user visits a regular Web page to manage his content. Instead of the server's being asked to deliver the finished UI on every click, though, the server sends back XML data and XSLT to draw a picture on the screen using the XML data. JavaScript is used to respond to user events, dynamically load new data, reload old data, and send updated data to the server.

As the user clicks to inspect different aspects of the data, the XSLT transform changes the view of the local XML data, which is in memory. This makes the redrawing exceptionally fast. Thus, the user perceives no "thunk" as the screen disappears and is redrawn.

This is a high-level view of the approach. More is discussed below.

Motivations

Looking at new technology always has its cost. Especially new technology which is, realistically, only implemented in two browsers. What is the benefit?

First and foremost, these techniques should help build a better end-user experience. If this XML-oriented approach does not deliver on this goal, then the conclusion must be that it failed.

Improving the UI response time is the primary way this approach improves the user experience. With an XML approach, we can decrease roundtrips to the server by keeping some server data local in the browser. We can also avoid the flicker of redrawing the entire screen.

Picking a technique that "fits the brain" of the target audience is another motivation. In general, UIs are created by creative people. Developers are not renowned for their good style with interfaces. Web designers have some experience with technologies such as CSS, JavaScript, and the DOM. They are, in some cases, learning new technologies such as XML. In most cases, though, new frameworks with evolving documentation are not very interesting to them. The technique described herein tries to shift some of the balance of power back to Web designers.

The third motivation involves consulting practices. Customers are most interested in how a project looks and acts, not how it is designed or implemented. Having early deliverables that are attractive keeps a project successful. This XML approach allows the UI team to develop independently of the developer team, with the two teams conferring at intervals. It is the XML representation, with a UI generated on the outside, that enables this. Adding schemas, such as Relax NG, helps keep the "contract" enforced between designers and developers.

The final motivation is interoperability. Content management systems need to share information with other systems and receive information from other systems. Presenting the data separate from a specific view of the data promotes this goal.

Getting Started

To begin, save the following as a file named 'xmlui1.xml':

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="xmlui1.xsl"?>
<folder>
<item>
<title>Doc 1</title>
</item>
<item>
<title>Doc 2</title>
</item>
</folder>

Next, save the following text as 'xmlui1.xsl':

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/folder">
<html>
<head>
<title>XML UI Demo</title>
</head>
<body>
<h1>XML UI Demo</h1>
<xsl:for-each select="item">
<p>
<xsl:value-of select="title"/>
</p>
</xsl:for-each>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Open the 'xmlui1.xml' file in Mozilla or Internet Explorer 5.5 or higher. You should see a screen that resembles the following:

Screenshot 1 - xmlui1 result

In this very simple example, we have an XML file that encodes the contents of a folder as an XML file. The stylesheet directive in line 2 of 'xmlui1.xml' links the XML file to an XSLT stylesheet, which transforms the XML into HTML for viewing. When the browser opens the XML file, it sees this instruction and automatically converts the data (XML) into presentation (HTML). The XSLT stylesheet is very simple. XSLT is a rule-driven template language, and this rule approach is by far the hardest part to getting started. This example has one rule, which matches on the "root node" of the source XML file using the pattern "/folder", i.e the rule is triggered by "/folder". After some HTML boilerplate, the 'xsl:for-each' element iterates over each element in "/folder", outputting the value of the 'title' subelement inside an HTML '<p>' tag.

This basic example was kept very simple, covering the basic goals:

  • Model your content using XML
  • Produce a view of the content using XSLT

The details to accomplish these goals:

  • Create an XML file on disk
  • Use an instruction to link to an XSLT file which produces HTML
  • Have a single rule in the template, to format the root folder

Developing with XML and XSLT can mean a lot of typing. Fortunately there are very good editors available, including an Emacs mode. I use the Oxygen editor, which provides very good debugging, validation, tag completion, and syntax highlighting.

This simple example, though, doesn't handle recursive folders. In the next example, we will get closer to modeling an actual Zope folder, while still using the filesystem to speed up development.

Modeling Zope Content and Multiple Rules

A Zope folder can contain many types of content. We could model this in XML using a vocabulary of tags for working with each kind of content, such as '<folder>', '<image>', '<file>', and '<pagetemplate>'. However, this would require a steadily growing vocabulary as we created new types.

To meet the minimum, we need to model folders and items, as we have done above. However, since a folder can contain other folders, we need to introduce recursion. Let's change our XML and XSLT to specify content type and enable them to handle recursion.

Save the following as 'xmlui2.xml':

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="xmlui2.xsl"?>
<folder>
<title>Site Folder</title>
<metatype>folder</metatype>
<item>
<title>Doc 1</title>
<metatype>zpt</metatype>
</item>
<item>
<title>File 1</title>
<metatype>file</metatype>
</item>
<folder>
<title>Folder 1.1</title>
<metatype>folder</metatype>
<item>
<title>Doc 1.1</title>
<metatype>zpt</metatype>
</item>
</folder>
<item>
<title>Doc 2</title>
<metatype>zpt</metatype>
</item>
</folder>

Next, save the following as 'xmlui2.xsl':

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<title>XML UI Demo</title>
<link href="xmlui2.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div class="xmlui">
<h1>XML UI Demo</h1>
<xsl:apply-templates select="folder"/>
</div>
</body>
</html>
</xsl:template>
<xsl:template match="folder">
<xsl:value-of select="metatype"/>: <xsl:apply-templates select="title"/>
<div class="folder">
<xsl:apply-templates select="folder|item"/>
</div>
</xsl:template>
<xsl:template match="item">
<div>
<xsl:value-of select="metatype"/>: 

Finally, save the following as 'xmlui2.css':

div.xmlui {
font-family: sans-serif;
margin-left: 1em;
}

div.folder {
margin-left: 0.8em;
}

span.title {
font-weight: bold;
}

Open the file 'xmlui2.xml' in Internet Explorer or Mozilla and you will see a nested tree. Below is a screenshot.

Screenshot 2 - xmlui2 result

While the changes to the XML file are simple, this example introduced a number of techniques into the XSLT. Foremost, we have adopted a rule structure, allowing us to descend into subfolders.

The top-most rule matches the root element and sets up the HTML. It contains the element '<xsl:apply-templates select="folder"/>'. This matches the first element in the source XML, which is the outermost '<folder>' element.

The rule '<xsl:template match="folder">' is the "handler" for this element. This rule inserts the metatype, applies a template for the '<title>' element, and recurses into more folders and items. This rule also wraps the child nodes in a '<div>' that has a style setting for indentation.

This one rule -- the handler for any '<folder>' element in the source XML -- shows all the relevant techniques. It is called as part of pattern-matching in the source XML. It then calls other rules as child elements are found. These rules that are called include this rule itself.

The XSLT also contains a rule to handle '<item>' elements and '<title>' elements.

Also, to keep the style clean, we moved CSS settings into a separate CSS file. This is linked in the '<head>' element of the XSLT, making it part of the output HTML.

Moving To Zope

We now have a model of our data and a template to give us a presentation of our data. This was developed and debugged without using Zope. Now that we have our ideas completed and the UI designed, we can begin integration.

The process is fairly simple:

  • Create a page template for 'xmlui3.xml' that generates the same structure.
  • Create a file object for 'xmlui3.xsl' that returns the correct MIME type.
  • Create a file object for 'xmlui3.css'.

First, copy the three files used above to new files: 'xmlui3.xml', 'xmlui3.xsl', and xmlui3.css'. In 'xmlui3.xml', change the second line so that it points at 'xmlui3.xsl' as the linked stylesheet. In 'xmlui3.xsl', change the '<link>' in the '<head>' so that it points at the new 'xmlui3.css' CSS file.

Create two File objects in a Zope folder by uploading the 'xmlui3.xsl' and 'xmlui3.css' files. No other steps are necessary for these two Files.

Next, create a Page Template object named 'xmlui3.xml' in the same folder by uploading the 'xmlui3.xml' file. You also need to change the 'Content-Type' field in the top-right of the edit screen to the value 'text/xml'.

Now click on the 'Test' tab for this 'xmlui3.xml' page template. You can see the static version from the previous example, now delivered by Zope.

We now need to replace the static XML with the actual folder contents. Using the ZMI, replace the contents of 'xmlui3.xml' with the following:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="xmlui3.xsl"?>
<folder xmlns:tal="http://xml.zope.org/namespaces/tal">
<title tal:content="container/title">Sample title</title>
<metatype tal:content="container/meta_type">Sample metatype</metatype>
<tal:block tal:repeat="folderitem container/objectValues">
<item>
<title tal:content="folderitem/id">Sample title</title>
<metatype tal:content="folderitem/meta_type">Sample
metatype</metatype>
</item>
</tal:block>
</folder>

This page template is quite simple. It adds the XML namespace for TAL, lays out the XML element for the current folder, then adds elements for all the folder data. This page template generates output that is similar to the static file. Thus, the XSLT that is linked can generate the HTML for viewing.

This template does not, however, recurse. We could add this to the page template, using some of the same Python recursion techniques of the various ZPT trees. On the other hand, we probably want dynamic loading when the tree is expanded, which is a topic for a different article.

Impact

As this article showed, modern browsers are capable of reading XML and dynamically generating interfaces. This can allow Web designers to work independently of the Zope component developers. Both simply have to agree on a "contract" for the representation of the data. This contract could be a Relax NG schema.

Also, development using this approach is, in some useful ways, easier than Zope templating. The debugging support of XML editors is much better than Zope error messages. The turnaround time of edit/view is much quicker, as only the filesystem is used. Finally, and importantly, there are many books on beginner and advanced XSLT, as well as thousands of recipes and snippets on the web. For dynamic HTML, the XML DOM and XSLT implementations in IE and Mozilla are far more similar than the HTML and JavaScript DOMs, which differ in painful ways.


Paul Everitt:

was co-founder of Zope Corporation, serving in a number of positions, including Vice President of Products, CEO, and Chief Strategy Officer.

Before co-founding Zope Corporation, Paul was an officer in the United States Navy. He received a degree in materials engineering from the University of Florida in 1990.

In 2002, Paul moved with his family to Rennes, France to start Zope Europe.


shim
shim  ZopeMag is committed to bringing you the best in Zope Documentation. shim
shim


Home   Subscribe   FAQ   Contact   Write for us   Privacy Policy   Weekly News   PyZine   opensourcexperts.com  

Reproduction of material from any of ZopeMag's pages without prior written permission is strictly prohibited. Copyright 2003 - 2005 ZopeMag Zope/Plone hosting by Nidelven IT