Subsections

 
7. Views

 
7.1 Intro

In this chapter we will introduce the 3 view technologies packaged with PyWork, how they work and how they should be used.

Views are the components that process the results of an Action and then format and output those results to the user's browser. They are represented by the "pywork.view.ViewHandler" class (which you can find in "pywork/view.py"). The 3 view techonologies included in the current PyWork ditribution are:

Also remember that you can customize the content type header by specifying it in pywork-map.xml, by default PyWork will set it to "text/html". At the time of writing this where the more useful and interesting technologies that we found. Each one has a different behaviour and advantages. Lets see in detail each one of them.

 
7.2 ZPT: Zope Page Templates

ZPT stands for Zope Page Templates developed and maintain by Zope (http://www.zope.org. ZPT is a templating system for XML and XHTML, by inserting special attributes to your XML tags ZPT interprets them and process the necessary python statements to produce an XML result. Here we won't explain ZPT, you will find the latest docs on http://dev.zope.org/Wikis/DevSite/Projects/ZPT/. But we will explain how it interacts with PyWork, for the next part we highly recommend that you read the ZPT documentation mentioned above. First, to enable a ZPT view you must define it in your "pywork-map.xml" by specifying the "view-handler" with "ZPT" directly or using one of the following extensions for your file: (.zpt , .zpt.html). PyWork defines only one context for ZPT: "here". Using TALES you can access your action with the "here" context. Notice that from ZPT you have access to all your object's methods, but we encourage you to mantain a set of readable properties to define the data to be accessed by a certain view. Let's see a very simple example. Here's the code for the action:

from pywork.action import Action

class MyAction(Action):

	def __init__(self):
		super(MyAction,self).__init__()
		self.__petList = ('Reptiles','Dogs','Cats','Birds')

	def __getPets(self):
		return self.__petList	

	pets = property(__getPets)

	def execute(self):
		return "pets_show"

The piece of "pywork-map.xml" that defines this action and its view:

<pywork-map>
	<action name="/mysimpleapp/pets.action" module="simpleapp.webactions" class="MyAction">
		<view name="pets_show" file="pets_show.zpt.html" view-handler="ZPT"/>
	</action>
</pywork-map>

And the file "pets_show.zpt.html":

<html>
<head><title>Simple App</title></head>
<body>
 We have this categories of pets:
 <span tal:repeat="cat here/pets">
	<span tal:replace="cat">sample category</span><br/>
 </span>
</body>
</html>

This example will output the following html:

<html>
<head><title>Simple App</title></head>
<body>
 We have this categories of pets:
 <span>
    Reptiles<br/>
    Dogs<br/>
    Cats<br/>
    Birds<br/>
 </span>
</body>
</html>

In this way you can access your action results and process your output, using ZPT powerful template syntax, to generate HTML and XML. You may also access (though is not recommended) python directly by the use of "python:" special TALES syntax. The variable "here" will also be available from there, pointing of course to the action that has executed, as well as all the builtin python functions.

 
7.3 XSLT: XSL Transformations

XSLT is a well known templating technique defined and created by the W3C, you can find the latest documentation here: http://www.w3.org/TR/xslt. It's a "programming language" in XML for processing XML. As before we will not explain the details of how XSLT works and how the the templates are constructed. We will give a description of what XML your XSLT view will receive in order to process it. The data available to an XSLT view is more restricted that the one to ZPT as an XML needs to be generated in order to apply to your XSL. First, to define an XLST view, you will either specify it in the "view-handler" attribute with "XSLT" or using one of the following extensions for your file: .xsl. PyWork generates XML of your action class following these simple rules.

Keeping this rules in mind you will always know what should be exposed to your XSL's. Again we recommend to expose readable properties as the convencional way to access your action results, and do not leave "public" attributes that you dont intend to access. Also for your convenience we have written this module in C and Python, so if you are able to build the C module (compiles on every platform Python does), you will get the highest performance, but don't worry the python version is also very fast. Let's continue to examin how the XML is generated (see pywork/util.py for more detailed information). The XML contains as the root node, the element "result", everything is put under this element. Furthermore, structures like list, sequence and dictionaries are introspected and output. Let's see a fairly complex example:

from pywork.action import Action
                                                                                                                                       
class Pet(object):
    def __init__(self):
        self.name = "Charly"
        self.type = "Dog"
                                                                                                                                       
class TestParent(object):
    def __init__(self):
        self.grandfather = "Armando"
        self.friends = ( "MARTIN", "JUAN", "LUCAS" )
                                                                                                                                       
class Test(TestParent):
    def __init__(self):
            super(Test,self).__init__()
            self.name = "Julian"
            self.surname = "Ciccale"
            self.__contact = { "PHONE":"1234567", "ADDRESS":('Re umberto','118') }
    def __getContact(self):
            return self.__contact
    contact = property(__getContact)

To get the XML version of this we can do this

	>>> from pywork.util import action2xml
	>>> action2xml(Test())
	<result><contact><PHONE>1234567</PHONE><ADDRESS><item>Re umberto</item><item>118</item></ADDRESS></contact><friends><item>MARTIN</item><item>JUAN</item><item>LUCAS</item></friends><grandfather>Armando</grandfather><name>Julian</name><surname>Ciccale</surname></result>
	>>>

Lets examine in more detail the XML

	<result>
	 <contact>
	  <PHONE>1234567</PHONE>
	  <ADDRESS>
	   <item>Re umberto</item>
	   <item>118</item>
	  </ADDRESS>
	 </contact>
	 <friends>
	  <item>MARTIN</item>
	  <item>JUAN</item>
	  <item>LUCAS</item>
	 </friends>
	 <grandfather>Armando</grandfather>
	 <name>Julian</name>
	 <surname>Ciccale</surname>
	</result>

In the above example we find differente elemnts, lets examine each one in detail:

Attention, for numbers you the python default str() method will be called so if you care about the format , please format it yourself and save it as a string. Please note that none of the "pywork.action.Action" attributes are output, this is done in purpose to avoid confussion and bad use of the tool. As stated int the above example, Sequences (List or Tuples) elements are inside an "item" XML element. And Dictionaries elements are inside an XML element with the name of the key.

Let's see how you would write an XSL to process the same information of the pets example showed in the ZPT section:

<html xsl:version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns="http://www.w3.org/TR/xhtml1/strict">
<head><title>Simple App</title></head>
<body>
 We have this categories of pets:
 <span>
  <xsl:for-each select="result/pets/item">
	<xsl:value-of select="text()"/><br/>
  </xsl:for-each>
 </span>
</body>
</html>

This will output the same HTML as the ZPT example.

 
7.4 PYTHON: Python

The Python view, provides you with a method of processing your action and printing the results directly to the HTTP response using python. It's intended for specialized uses and not to generate XML/HTML as the templatized views are. It may serve to you to do special action manipulation, to generate images, PDFs, and any other kind of data. PyWork uses this view as the default view if no "view-handler" is specified, or if "view-handler" is "PYTHON", or if your files end with .py . The file specified in the configuration file must be in this format "module<.submodule>*.function". PyWork will call your function with the action executed as the only parameter and will expect a string to ouput in the HTTP response. For example if you have a moduled named "myapp" with a submodule (normally a python file) named "images" and a function there called "gengif" you would specify it as: "myapp.images.gengif". Remember that you can control the content-type in your pywork-map.xml configuration!

 
7.5 Metadata

PyWork creates a metadata object for each "view" element specified in pywork-map.xml, then creates a dictionary for each one, with its name as key and saves them in the action "_descriptor" attribute as "views" (see the Action chapter). The metadata class for views is "ViewDescriptor" ("pywork/descriptor.py").

See About this document... for information on suggesting changes.