ZPTwithFormulatorPartII
Formulator with ZPT: Part 2
This is a followup to beno 's most excellent ZPT tutorial
Introduction
In the documentation for the Formulator product, there is a section that discusses how to retrieve Formulator data and objects automatically, without haveing to type all your elements, one-by-one. This How-To shows how to do this with ZPT, and as an extra bonus, we show how to do this utilizing the groups you can setup in the Formulator admin interface.
For this HowTo, we will use a registration form as an example.
Display: Data Entry (Zope Page Templates)
Create a form object and populate it in your base directory:
forms/regsitration
which will be access like this:
here/portal_url/forms/registration
Once you have created a Forumator object and have
your form elements defined, create a new "Page
Template" wherever you want. For this example, we
created one called reggroups
in the portal base
directory. Here is the content of the ZPT:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US" metal:use-macro="here/main_template/macros/master"> <body> <div metal:fill-slot="main" tal:define="thisform here/portal_url/forms/registration"> <form tal:attributes="action thisform/action; method thisform/method; name thisform/name; encoding thisform/enctype; "> <h3><span tal:replace="thisform/title" /></h3> <table> <tr tal:define="elements thisform/get_fields" tal:repeat="element elements "> <tal:bloc tal:define="display element/title_or_id; field element/id; value python:element.get_value('default'); "> <td> <span tal:content="display" />: </td> <td> <span tal:replace="structure element/render" /> <br> </td> </tal:bloc> </tr> </table> </form> </div> </body> </html>
The form attributes are pulled from the form object, so we don't need to touch this code if those change - we just have to make the changes in the ZMI under the "Settings" tab for your form.
Now, to spice things up (and make life much faster/easier, check out the "Order" tab in the ZMI, and build some neat groups. Now, we need to rewrite our page template so that we can take advantage of this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US" metal:use-macro="here/main_template/macros/master"> <body> <div metal:fill-slot="main" tal:define="thisform here/portal_url/forms/registration"> <form tal:attributes="action thisform/action; method thisform/method; name thisform/name; encoding thisform/enctype; "> <h3><span tal:replace="thisform/title" /></h3> <table tal:define="groups thisform/get_groups" tal:repeat="group groups "> <tr> <td colspan="2"> <h4><span tal:replace="group/title" /></h4> </td> </tr> <tr tal:define="elements python:thisform.get_fields_in_group(group)" tal:repeat="element elements "> <tal:bloc tal:define="display element/title_or_id; field element/id; value python:element.get_value('default'); "> <td> <span tal:content="display" />: </td> <td> <span tal:replace="structure element/render" /> <br> </td> </tal:bloc> </tr> <tr> <td> <p> </p> </td> </tr> </table> </form> </div> </body> </html>
Logic: Data Parsing/Insertion (Python External Method)
We are using a MySQL? database for this example, with data that will be inserted into multiple tables. We also want to make this easily maintainable, without any reference to a particular particlar fields. This way, if we change the table structure, we don't have to worry about going back and changing ourcode.
Given these requirements, an external method seemed the best choice. Here's what we came up with :
import
Display: Confirmation Page (Zope Page Templates)
Here we want to present the end user with something friednly after they have hit the submit button and their data hase been inserted into the appropriate place.