Re: [Zope] How to make a ZPT-based form that calls itself? (Part II)
On 5/19/05, Ken Winter [EMAIL PROTECTED] wrote: The difference between this and the deletion example is that this form (personform.htm) need to be called with an argument, giving the person_id that identifies the record it is supposed to display. I have tried a number of ways to sneak this argument in, but my limited experience with Zope/Python syntax has left me unable to guess the right trick. Well, the generic method is to create a script that you call in the start of you ZPT that returns a dictionary with all the data to be displayed. This can also be the same script that actually does the deletion. http://blogs.nuxeo.com/sections/blogs/lennart_regebro/2005_04_19_python_statement/ May explain it a bit more, and if not, I should write something clearer. :^) -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.cps-project.org/ ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
RE: [Zope] How to make a ZPT-based form that calls itself? (Part II)
-Original Message- From: Lennart Regebro [mailto:[EMAIL PROTECTED] Sent: Thursday, May 19, 2005 4:36 AM To: [EMAIL PROTECTED] Cc: J Cameron Cooper; zope@zope.org Subject: Re: [Zope] How to make a ZPT-based form that calls itself? (Part II) On 5/19/05, Ken Winter [EMAIL PROTECTED] wrote: The difference between this and the deletion example is that this form (personform.htm) need to be called with an argument, giving the person_id that identifies the record it is supposed to display. I have tried a number of ways to sneak this argument in, but my limited experience with Zope/Python syntax has left me unable to guess the right trick. Well, the generic method is to create a script that you call in the start of you ZPT that returns a dictionary with all the data to be displayed. This can also be the same script that actually does the deletion. http://blogs.nuxeo.com/sections/blogs/lennart_regebro/2005_04_19_python_st atement/ May explain it a bit more, and if not, I should write something clearer. Nor clearer - your blog is quite clear - but more elementary, for us novices. I'm very attracted to your idea of one Python call that takes care of returning all the data that the page needs. But I'm not sure just what you are including in the term data: * I assume you include data retrieved from (and updated in) an underlying relational database. * Does data also include parameters (or arguments, or query string variables, or whatever you call them) passed from one HTML page to the next? This parameter-passing is what I seem to be having trouble with. How does that script get the info it needs from the previous page? In my example, when my personform.htm updates a record and then re-calls itself, how does it get the person_id identifying the record it's supposed to display the second time around? I have a feeling that there's some point I'm just not getting here, but that I'm too new to this to figure out what it is. - Ken ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] How to make a ZPT-based form that calls itself? (Part II)
On 5/19/05, Ken Winter [EMAIL PROTECTED] wrote: * I assume you include data retrieved from (and updated in) an underlying relational database. * Does data also include parameters (or arguments, or query string variables, or whatever you call them) passed from one HTML page to the next? Sure. This parameter-passing is what I seem to be having trouble with. How does that script get the info it needs from the previous page? In my example, when my personform.htm updates a record and then re-calls itself, how does it get the person_id identifying the record it's supposed to display the second time around? You put it in a hidden input-field. I have a feeling that there's some point I'm just not getting here, but that I'm too new to this to figure out what it is. -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.cps-project.org/ ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
RE: [Zope] How to make a ZPT-based form that calls itself? (Part II)
-Original Message- From: Lennart Regebro [mailto:[EMAIL PROTECTED] Sent: Thursday, May 19, 2005 11:07 AM To: [EMAIL PROTECTED] Cc: J Cameron Cooper; zope@zope.org Subject: Re: [Zope] How to make a ZPT-based form that calls itself? (Part II) On 5/19/05, Ken Winter [EMAIL PROTECTED] wrote: * I assume you include data retrieved from (and updated in) an underlying relational database. * Does data also include parameters (or arguments, or query string variables, or whatever you call them) passed from one HTML page to the next? Sure. This parameter-passing is what I seem to be having trouble with. How does that script get the info it needs from the previous page? In my example, when my personform.htm updates a record and then re-calls itself, how does it get the person_id identifying the record it's supposed to display the second time around? You put it in a hidden input-field. That's what I've been doing (I think), and it's not working. Let me paste in a listing of the whole div tag that I'm using (with some irrelevant bits clipped out): div tal:repeat=person python:here.dbobs.read_person_by_id_py(context.REQUEST.person_id) table height=fit width=fit border=0 align=left cellpadding=0 cellspacing=0 tr height=fit ... td width=fit align=left emstrong font size=+2p align=left tal:content=string: ${person/first_name} ${person/middle_names} ${person/last_name}Name Filler/p/font /strong/em/td /tr /tablebr pnbsp;/pbr form name=form1 id=form1 method=post action=dbobs/update_person_py table width=fit border=0 cellspacing=0 cellpadding=0 tr height=fit td width=fit align=rightemnbsp;nbsp;First Name:nbsp;/em/td td width=fitinput type=text name=first_name value= tal:attributes=value string:${person/first_name}//td /tr tr height=fit td width=fit align=rightemnbsp;nbsp;Middle Name(s):nbsp;/em/td td width=fitinput type=text name=middle_names value= tal:attributes=value string:${person/middle_names}//td /tr tr height=fit td width=fit align=rightemnbsp;nbsp;Last Name:nbsp;/em/td td width=fitinput type=text name=last_name value= tal:attributes=value string:${person/last_name}//td /tr /table input type=hidden name=person_id value= tal:attributes=value string:${person/person_id}/ p input type=submit name=Submit value=Save Changes / input type=reset name=Reset value=Cancel Changes / /p /form /div The tal:repeat in the first line is my attempt to grab all my data at the start. The hidden input field at the bottom is my attempt to pass the person_id along when the page is trying to re-call itself. The whole thing works OK when the page is called from elsewhere, passing the person_id in the form of a URL argument string along these lines: personform.htm?person_id=35. But it doesn't work when the Python script update_person_py() called by personform.htm itself tries to re-call personform.htm, trusting the hidden field to convey the person_id data. Instead, the data update is performed but the next thing the browser shows is an AttributeError=person_id. The body of the update_person_py script is: id = context.REQUEST.get('person_id') if id: container.update_person(\ person_id=id,\ first_name=context.REQUEST.get('first_name'),\ middle_names=context.REQUEST.get('middle_names'),\ last_name=context.REQUEST.get('last_name')) context.REQUEST.RESPONSE.redirect('personform.htm') What's wrong with this picture? - Thanks again, Ken ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] How to make a ZPT-based form that calls itself? (Part II)
What's wrong with this picture? This: context.REQUEST.RESPONSE.redirect('personform.htm') When you do this, you loose everything in the form. When you then in the personform.htm do context.REQUEST.person_id you get a key-error. -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.cps-project.org/ ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
RE: [Zope] How to make a ZPT-based form that calls itself? (Part II)
-Original Message- From: Lennart Regebro [mailto:[EMAIL PROTECTED] Sent: Thursday, May 19, 2005 12:03 PM To: [EMAIL PROTECTED] Cc: J Cameron Cooper; zope@zope.org Subject: Re: [Zope] How to make a ZPT-based form that calls itself? (Part II) What's wrong with this picture? This: context.REQUEST.RESPONSE.redirect('personform.htm') When you do this, you loose everything in the form. When you then in the personform.htm do context.REQUEST.person_id you get a key-error. Assuming the data loss is due to the 'redirect', I tried substituting this alternative line, suggested by JCC earlier, into the script: context['personform.htm']() But that just changed the error to KeyError: 'personform_htm'. ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] How to make a ZPT-based form that calls itself? (Part II)
On 5/19/05, Ken Winter [EMAIL PROTECTED] wrote: But that just changed the error to KeyError: 'personform_htm'. Well, it's 'personform.htm', not undescore, right? -- Lennart Regebro, Nuxeo http://www.nuxeo.com/ CPS Content Management http://www.cps-project.org/ ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
RE: [Zope] How to make a ZPT-based form that calls itself? (Part II)
Am Donnerstag, den 19.05.2005, 11:56 -0400 schrieb Ken Winter: -Original Message- From: Lennart Regebro [mailto:[EMAIL PROTECTED] Sent: Thursday, May 19, 2005 11:07 AM To: [EMAIL PROTECTED] Cc: J Cameron Cooper; zope@zope.org Subject: Re: [Zope] How to make a ZPT-based form that calls itself? (Part II) On 5/19/05, Ken Winter [EMAIL PROTECTED] wrote: * I assume you include data retrieved from (and updated in) an underlying relational database. * Does data also include parameters (or arguments, or query string variables, or whatever you call them) passed from one HTML page to the next? Sure. This parameter-passing is what I seem to be having trouble with. How does that script get the info it needs from the previous page? In my example, when my personform.htm updates a record and then re-calls itself, how does it get the person_id identifying the record it's supposed to display the second time around? You put it in a hidden input-field. That's what I've been doing (I think), and it's not working. Let me paste in a listing of the whole div tag that I'm using (with some irrelevant bits clipped out): div tal:repeat=person python:here.dbobs.read_person_by_id_py(context.REQUEST.person_id) the read_person_by_id_py can probably read the request variable by its own. So no need to pass it like that. table height=fit width=fit border=0 align=left cellpadding=0 cellspacing=0 tr height=fit ... td width=fit align=left emstrong font size=+2p align=left tal:content=string: Ugh! Make yourself familar with moden HTML and CSS, this saves a lot of typing - and makes smaller templates. ${person/first_name} ${person/middle_names} ${person/last_name}Name Filler/p/font /strong/em/td /tr /tablebr pnbsp;/pbr form name=form1 id=form1 method=post action=dbobs/update_person_py table width=fit border=0 cellspacing=0 cellpadding=0 tr height=fit td width=fit align=rightemnbsp;nbsp;First Name:nbsp;/em/td td width=fitinput type=text name=first_name value= tal:attributes=value string:${person/first_name}//td value person/first_name would be ok. /tr tr height=fit td width=fit align=rightemnbsp;nbsp;Middle Name(s):nbsp;/em/td td width=fitinput type=text name=middle_names value= tal:attributes=value string:${person/middle_names}//td /tr tr height=fit td width=fit align=rightemnbsp;nbsp;Last Name:nbsp;/em/td td width=fitinput type=text name=last_name value= tal:attributes=value string:${person/last_name}//td /tr /table input type=hidden name=person_id value= tal:attributes=value string:${person/person_id}/ p input type=submit name=Submit value=Save Changes / input type=reset name=Reset value=Cancel Changes / /p /form /div The tal:repeat in the first line is my attempt to grab all my data at the start. The hidden input field at the bottom is my attempt to pass the person_id along when the page is trying to re-call itself. The whole thing works OK when the page is called from elsewhere, passing the person_id in the form of a URL argument string along these lines: personform.htm?person_id=35. But it doesn't work when the Python script update_person_py() called by personform.htm itself tries to re-call personform.htm, trusting the hidden field to convey the person_id data. Instead, the data update is performed but the next thing the browser shows is an AttributeError=person_id. The body of the update_person_py script is: id = context.REQUEST.get('person_id') if id: container.update_person(\ person_id=id,\ first_name=context.REQUEST.get('first_name'),\ middle_names=context.REQUEST.get('middle_names'),\ last_name=context.REQUEST.get('last_name')) context.REQUEST.RESPONSE.redirect('personform.htm') the redirect above when the script is included like you shown, causes the header: location: to be set. Then Zope outputs all the HTML from ZPT and the browser reads the location: header and makes a new request with the URL found there. This new request obviously misses all the form information. What's wrong with this picture? I'd use the controller-script approach here. This is, you have the python script, which checks the REQUEST for form information and perhaps initialize some variables with default data. value=context.REQUEST.get('value',default) is the pattern here. You would check for the name of the submit button or some essential form data. Depending on action, do your updates in database or whatever. Next read data out of database. Usually you connect this to a preparation of data for the template. The pattern is like this: somedata=[{'value1':r.value1, # use comments a lot 'value2':r.value2, # possibly in every 'value3':r.value3+r.value4 # line
RE: [Zope] How to make a ZPT-based form that calls itself? (Part II)
In Part I, J Cameron Cooper showed me how to write a ZPT-based form that displayed a list of database records and gave the user a chance to delete one of them, after which the form redisplayed itself with a refreshed list that reflected the deletion just performed. The core of this was this Python script, which was called by the form and which called a Z SQL method to do the deletion: id = context.REQUEST.get('person_id') if id: container.delete_person(person_id=id) context.REQUEST.RESPONSE.redirect('deltest.htm') Now what I need to do is implement a record update form. This form displays all the columns of one database record. The columns values are shown in text input fields. The user can write new values into these fields and push a submit button, which calls this Python script: id = context.REQUEST.get('person_id') if id: container.update_person(\ person_id=id,\ first_name=context.REQUEST.get('first_name'),\ middle_names=context.REQUEST.get('middle_names'),\ last_name=context.REQUEST.get('last_name')) context.REQUEST.RESPONSE.redirect('personform.htm') This performs the update OK, but instead of redisplaying the page it gives me: Site Error An error was encountered while publishing this resource. Error Type: AttributeError Error Value: person_id The difference between this and the deletion example is that this form (personform.htm) need to be called with an argument, giving the person_id that identifies the record it is supposed to display. I have tried a number of ways to sneak this argument in, but my limited experience with Zope/Python syntax has left me unable to guess the right trick. - Thanks for your help, Ken -Original Message- From: J Cameron Cooper [mailto:[EMAIL PROTECTED] Sent: Wednesday, May 11, 2005 5:52 PM To: [EMAIL PROTECTED] Cc: zope@zope.org Subject: Re: [Zope] How to make a ZPT-based form that calls itself? Ken Winter wrote: -Original Message- From: J Cameron Cooper [mailto:[EMAIL PROTECTED] Sent: Wednesday, May 11, 2005 4:27 PM To: [EMAIL PROTECTED] Cc: zope@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... ... ...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? Look at your Python. It understands a dot as an attribute access. That's why Zope historically avoids dotted object names. Witness 'index_html'. You may use dictionary lookup: context['deltest.htm']() or getattr. 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? Correct. Why in that case is a redirect better? Because you don't end up on the script (no bad bookmark), and reload of that page won't carry the previous POST payload. See the very recent post about redirect-after-post.
Re: [Zope] How to make a ZPT-based form that calls itself? (Part II)
On Wed, May 18, 2005 at 07:32:29PM -0400, Ken Winter wrote: The difference between this and the deletion example is that this form (personform.htm) need to be called with an argument, giving the person_id that identifies the record it is supposed to display. I have tried a number of ways to sneak this argument in, but my limited experience with Zope/Python syntax has left me unable to guess the right trick. You can append it to the url as a query parameter. e.g.: response.redirect('some_page?some_parameter=%s' % some_value) -- Paul Winkler http://www.slinkp.com ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
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=topfont color=#00 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=0font 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 pId 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 pThe quot;Idsquot; are the numbers in front of each person's name./p pa href=deltest.htmRefresh 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') In your case, since this is a destructive method, you probably want do a redirect, back to your listing. 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.) --jcc -- Building Websites with Plone http://plonebook.packtpub.com/ ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
RE: [Zope] How to make a ZPT-based form that calls itself?
-Original Message- From: J Cameron Cooper [mailto:[EMAIL PROTECTED] Sent: Wednesday, May 11, 2005 4:27 PM To: [EMAIL PROTECTED] Cc: zope@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=topfont color=#00 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=0font 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 pId 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 pThe quot;Idsquot; are the numbers in front of each person's name./p pa href=deltest.htmRefresh 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 ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] How to make a ZPT-based form that calls itself?
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() Of course it didn't, there's no object called deltest and the object that's not there certainly doesn't have a method called htm. Think about Python syntax - the . delimits a class containment hierarchy. Zope allows you to have the . in object names, which I disagree with, so you have to use getattr(context, 'deltext.htm')() to get the actual object. -- Phillip Hutchings http://www.sitharus.com/ [EMAIL PROTECTED] / [EMAIL PROTECTED] ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] How to make a ZPT-based form that calls itself?
Ken Winter wrote: -Original Message- From: J Cameron Cooper [mailto:[EMAIL PROTECTED] Sent: Wednesday, May 11, 2005 4:27 PM To: [EMAIL PROTECTED] Cc: zope@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... ... ...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? Look at your Python. It understands a dot as an attribute access. That's why Zope historically avoids dotted object names. Witness 'index_html'. You may use dictionary lookup: context['deltest.htm']() or getattr. 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? Correct. Why in that case is a redirect better? Because you don't end up on the script (no bad bookmark), and reload of that page won't carry the previous POST payload. See the very recent post about redirect-after-post. 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? A Plone site it a superset of a CMF site. But it you're outside a CMF framework entirely, formcontroller may not work, as it needs to install a tool. Dunno if it'll install standalone. --jcc -- Building Websites with Plone http://plonebook.packtpub.com/ ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] How to make a ZPT-based form that calls itself?
On Wed, May 11, 2005 at 04:51:33PM -0500, J Cameron Cooper wrote: Look at your Python. It understands a dot as an attribute access. That's why Zope historically avoids dotted object names. Witness 'index_html'. You may use dictionary lookup: context['deltest.htm']() or getattr. But note that they're not semantically equivalent. getattr(foo, 'bar') might use acquisition to find 'bar'. foo['bar'] does not use acquisition, it only looks directly in foo. I don't like this difference, but, whatever. -- Paul Winkler http://www.slinkp.com ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )