[Zope] How to make a ZPT-based form that calls itself?

Ken Winter ken at sunward.org
Wed May 11 17:21:43 EDT 2005


> -----Original Message-----
> From: J Cameron Cooper [mailto:zope-l at jcameroncooper.com]
> Sent: Wednesday, May 11, 2005 4:27 PM
> To: ken at sunward.org
> Cc: zope at zope.org
> Subject: Re: [Zope] How to make a ZPT-based form that calls itself?
> 
> Ken Winter wrote:
> > Hi Zopers -
> >
> > I'm trying to make a ZPT-based HTML form that:
> >
> > 1. Displays the records in a MySQL 'Person' table;
> > 2. Offers a field for updating this table (in my simple test example, it
> > accepts the Id of a Person to delete);
> > 3. When you push its 'Submit' button, updates the database; and then
> > 4. Automatically redisplays itself, showing the updated 'Person'
> records.
> >
> > After a lot of help from the folks on various Zope lists, I've made it
> > through steps 1-3, but I'm stuck on step 4 and I can't find an example
> or
> > tutorial telling me how to do it.
> >
> > The relevant code snippets are:
> >
> > The ZPT's body...
> >
> > <table width="100%" height="100%" border="0" cellpadding="6"
> > cellspacing="0">
> >   <tr>
> >     <td width="1084" height="531" align="left" valign="top"><font
> > color="#000000" face="Verdana, Arial, Helvetica, sans-serif"><!--
> > InstanceBeginEditable name="Base" -->
> >       <h1> People (deletion test)</h1>
> >       <table tal:repeat="row here/dbobs/read_all_people" width="100%"
> > border="0" cellspacing="0" cellpadding="0"><font face="Verdana, Arial,
> > Helvetica, sans-serif">
> >         <tr>
> >           <td width="44%" tal:content="string:${row/person_id} -
> > ${row/first_name} ${row/middle_names} ${row/last_name}">Filler</td>
> >           <td width="56%">&nbsp;</td>
> >         </tr>
> >       </table>
> >       <p></p>
> >       <form action="dbobs/delete_person_py" method="post"
> > name="delete_form">
> >         <p>Id of Person To Delete:
> >           <input type="text" name="person_id:int" />
> >         </p>
> >         <p>
> >           <input name="do_delete" type="submit" id="do_delete"
> value="Delete
> > this Person" />
> >         </p>
> >       </form>
> >       <p>The &quot;Ids&quot; are the numbers in front of each person's
> > name.</p>
> >       <p><a href="deltest.htm">Refresh This Page</a></p>
> >       <p tal:replace="python:here.dbobs.test1('MyParamValue')">Junk</p>
> 
> >       <!-- InstanceEndEditable --></font></td>
> >   </tr>
> > </table>
> >
> > ...The one-line Python script "delete_person_py" that the form's action
> > attribute calls...
> >
> > container.delete_person(person_id=context.REQUEST.get('person_id'))
> >
> > ...The Z SQL method delete_person(person_id) that the Python script
> calls...
> >
> > delete from person where <dtml-sqltest person_id op=eq type=int>
> >
> > ...And a URL to the test page in its current incarnation...
> >
> > http://dhat.vega.zettai.net/clients/ridhwan/dhr3/deltest.htm
> >
> > What's wrong with this page is that you have to hit the "Refresh This
> Page"
> > link to get it to do what I want it to do automatically.
> >
> > I suspect that what I'm missing is some basic HTML knowledge.  But
> whatever
> > it is, I'd appreciate your help in suggesting the missing piece.
> 
> You submit to a script, going that url, and the script is responsible
> for providing the output of the page.
> 
> Since you write no output, you see no action in your browser. Some
> browsers may display a blank page, which probably would have been more
> helpful to you.
> 
> You want your script to do something. It might print out some text to
> form HTML, but that's nasty. It usually will either (a) call some other
> object, like a page template, to provide output, or (b) do a redirect.
> 
> Case A:
>    return context.some_page()
> 
> Case B:
>    context.REQUEST.RESPONSE.redirect('some_page')
> 
GREAT!!  Case B works perfectly (and it would have taken me forever to guess
this solution).  Case A didn't work when written as 

return context.deltest.htm()

but, who cares?

> In your case, since this is a destructive method, you probably want do a
> redirect, back to your listing.

"Destructive" means that the script has a side-effect (deleting the Person),
right?  Why in that case is a redirect better?

> A more advanced and flexible technique is to use FormController. With
> that, you specify by configuration if you want redirect or traverse and
> where to go based on the results of the script (success, failure, some
> other state.)

I'm looking into this - looks promising at first glance.  I note that the
Add dialog warns that "these are normally useful only inside a CMF site."
Mine is not (at least currently) a CMF site.  Should I worry about that?

Anyway, thanks so much for getting me over this hurdle!

- Ken




More information about the Zope mailing list