# HG changeset patch # User paulb # Date 1121784569 0 # Node ID 0dcd6eda32bea18b1ac8ccff4222b948cac45873 # Parent 8d1ae6f73f7e06226f6aeaca5a8b667b3f037b70 [project @ 2005-07-19 14:49:29 by paulb] Added a Web resource implementation document. Suggested a template filename. Added notes about selector names. Changed the name of the multiple-choice document to multiple.html. diff -r 8d1ae6f73f7e -r 0dcd6eda32be docs/Web-resource.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/Web-resource.html Tue Jul 19 14:49:29 2005 +0000 @@ -0,0 +1,126 @@ + + +
+ +With a completed template after the design, +structure annotation and selector annotation, we may now write a Web +resource which will expose our form as a Web application, allowing +users to input information and to manipulate that information using +their Web browser. Whilst XSLForms is just a normal Python package +which can be used from many kinds of programs and environments, we +shall concentrate on using the built-in WebStack +support to build a +WebStack application around our form template.
+In the directory structure created
+earlier, we now want to edit the __init__.py
file and
+add code which will do most of the work of the form-editing
+application. Here is the start of this code:
#!/usr/bin/env python+
"A very simple example application."
import WebStack.Generic
import XSLForms.Resources
import XSLForms.Utils
import os
# Resource classes.
class VerySimpleResource(XSLForms.Resources.XSLFormsResource):
# To be continued.
The above import statements just include in our application +everything that it is likely to need from WebStack, XSLForms and the +standard library. Then, we define a class inheriting from a special +XSLForms class which does some of the tedious Web application +housekeeping that we would otherwise need to do ourselves.
+We may expand the above class definition as follows:
+class VerySimpleResource(XSLForms.Resources.XSLFormsResource):+
"A very simple resource providing a hierarchy of editable fields."
resource_dir = os.path.join(os.path.split(__file__)[0], "Resources")
encoding = "utf-8"
template_resources = {
"structure" : ("structure_template.xhtml", "structure_output.xsl")
}
def respond_to_form(self, trans, form):
"""
Respond to a request having the given transaction 'trans' and the given
'form' information.
"""
# To be continued.
The class is started with some attribute definitions:
+resource_dir
attribute is used to locate
+the template, stylesheet and other non-Python resources. We calculate
+this attribute by taking the location of the Python package itself and
+finding the Resources
subdirectory, just as described
+in the directory structure document.encoding
attribute is not strictly
+necessary, but it states which character encoding will be used in the
+Web pages generated by the template, and UTF-8 is a safe choice in most
+situations.template_resources
attribute is a
+dictionary mapping a name onto details about our template and the
+stylesheet that will actually produce the Web pages for each form being
+edited.structure
(since
+the root element of the form data is always structure
)Resources
+directory: structure_template.xhtml
(if the suggested
+name was used)structure_output.xsl
The class also has a method which resembles the typical respond
+method of normal WebStack
+resources: the respond_to_form
method is, in fact, a
+special version of that method providing ready-to-use information about
+the form (or forms) being edited.
We may now add to the above method definition by considering what +the resource needs to do when being sent a request by a user of the +application.
+First of all, we need to inspect the form
object
+to see if any form data is available. Since the data is provided
+throughout XSLForms as XML documents, we call the get_documents
+method on the form
object:
documents = form.get_documents()+
As a result of this method, we should now have a dictionary mapping
+form names to XML documents containing form data. However, it is not
+guaranteed that the form data for our chosen form, structure
,
+even exists since a user may be visiting the resource for the first
+time.
Therefore, we test to see if the structure
+document exists, creating a new document if it did not:
# Ensure the presence of a document.+
if documents.has_key("structure"):
structure = documents["structure"]
else:
structure = form.new_instance("structure")
Now we should have a document containing the data for the form being +edited, regardless of whether any form was filled out and submitted or +whether we have created a new one for that purpose.
+It may be the case that a user pressed a button in order to add or
+remove items or subitems from the form. We must respond to such things
+by examining the selector information to see which parts of the structure
+document are affected:
# Add and remove elements according to the selectors found.+
selectors = form.get_selectors()
The result of get_selectors
is a dictionary mapping
+selector names to lists of nodes affected by each particular
+selector. In the selector annotation
+process, we defined selectors for the addition and removal of items and
+subitems, and for convenience we pass the results for each selector to
+a special function to perform the appropriate operation for us:
XSLForms.Utils.remove_elements(selectors.get("remove2"))+
XSLForms.Utils.add_elements(selectors.get("add2"), "subitem")
XSLForms.Utils.remove_elements(selectors.get("remove"))
XSLForms.Utils.add_elements(selectors.get("add"), "item")
Finally, we are ready to present the edited form data. In typical +WebStack fashion, we emit the content type of the final output along +with our chosen character encoding:
+# Start the response.+
trans.set_content_type(WebStack.Generic.ContentType("application/xhtml+xml", self.encoding))
Then, we ensure that our template is ready to use by calling the
+superclass's prepare_output
method with the name of
+the form:
# Ensure that an output stylesheet exists.+
trans_xsl = self.prepare_output("structure")
This prepares the stylesheet whose file is named in the template_resources
+attribute entry, and this stylesheet is then sent to the
+superclass's send_output
method as part of a list of
+stylesheets (although we only use a single stylesheet in this example)
+along with the form data itself:
# Complete the response.+
self.send_output(trans, [trans_xsl], structure)
At this point, the user should receive their edited form and be able +to make more modifications.
+We should now have an application which can be deployed and tested +using the usual WebStack techniques. However, more advanced templates +can be designed, and we shall consider multiple-choice +fields in the next activity in the development process.
+ + diff -r 8d1ae6f73f7e -r 0dcd6eda32be docs/design.html --- a/docs/design.html Tue Jul 19 14:46:59 2005 +0000 +++ b/docs/design.html Tue Jul 19 14:49:29 2005 +0000 @@ -115,7 +115,8 @@<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Example</title>
</head>
<body>
<form action="" method="POST">
<!-- Template text between the start and the interesting part. -->
<div>
<p>
Some item: <input name="value" type="text" value="some value" />
<input name="remove" type="submit" value="Remove" />
</p>
<p>
Itself containing more items:
</p>
<p>
Sub-item: <input name="subvalue" type="text" value="some other value" />
<input name="remove2" type="submit" value="Remove" />
</p>
<p>
<input name="add2" type="submit" value="Add subitem" />
</p>
</div>
<p>
<input name="add" type="submit" value="Add item" />
</p>
<!-- Template text between the interesting part and the end. -->
</form>
</body>
</html>
Once you are happy with the
design of the page, save it to the directory
-created earlier, then proceed to adding
+created earlier (perhaps choosing the name structure_template.xhtml
),
+then proceed to adding
structure information in the next stage of the process.
The recommended directory structure of an XSLForms application is as +
The recommended directory +structure of an XSLForms application is as follows:
- -- - | Example Directory Structure - + | Example
+Directory
+Structure |
-
-
|||
---|---|---|---|---|---|
A top-level directory corresponding to a Python package | - -VerySimple -__init__.py |
-
- - + | A +top-level directory corresponding to a Python package | +VerySimple |
+ |
A subdirectory containing non-code resources for the + | A subdirectory +containing non-code resources for the application | - -- + | Resources - -... |
-
+ Resources |
For the above example, the directory structure would be created using UNIX-style commands as follows:
- - +For the above example, the +directory structure would be created using UNIX-style commands +as follows:
mkdir VerySimple- - -
mkdir VerySimple/Resources
touch VerySimple/__init__.py
It is in the Resources
subdirectory that we will save
-our template files when designing them as
-part of the next activity in the application development process.
It is in the Resources
+subdirectory that we will save
+our template files when designing
+them as
+part of the next activity in the application development process.
diff -r 8d1ae6f73f7e -r 0dcd6eda32be docs/directory.html --- a/docs/directory.html Tue Jul 19 14:46:59 2005 +0000 +++ b/docs/directory.html Tue Jul 19 14:49:29 2005 +0000 @@ -1,91 +1,60 @@
- - - - - - - - - -
- - - - - + - -