You are not logged in Log in Join
You are here: Home » Members » jim » ZopeSecurity » GetAndPostToSamePage

Log in
Name

Password

 
 

History for GetAndPostToSamePage

??changed:
-
New Standard Idiot: GET and POST to same page

  In the beginning there was Bobo and it was good.  In our innocence,
  we used pages to display the state of an objects with an editing
  interface (e.g. manage_main), and methods to do the edit
  (manage_edit).  After performing an edit, we'd typically just call
  the display page (manage_main) from manage_edit.  This seemed to
  work well for a while.

  Later, we noticed that the display page would sometimes get confused
  because it was displayed via the "wrong" URL.  To get around this,
  we started using redirects to make the browser visit the display
  page after the edit. This has the obvious downside of causing a
  separate request to be made. Also, some clients may not handle
  redirects predictably.

  An alternative would be to use the same URL for display and edit.  A
  display page could be written in such a way that if a request was a
  POST, the edit method would be called internally before executing
  the display logic.  If there was an input error, then the form would
  be displayed with the data from the request and any input error
  messages.

  A simple example. 

    Suppose we have an object that has an interface
    for managing two properties, 'title' and 'text'. Title is a simple
    string and text is a possibly-multi-line string.

    We *might* have something like::

       <html><body>

          <dtml-form post="main_post" 
             errors="errors,title_error,text_error">

             <dtml-if errors>
               <hr><font color="red"><ul>
                  <dtml-in errors>
                    <li>&dtml-sequence-var;</li>
                  </dtml-in>                    
               </ul></font><hr>
             </dtml-if>

             Title: 
                <dtml-if title_error>
                  <font color="red">&title_error;</font>
                </dtml-if>
                <br><input name=title value="&dtml-title;">
             Text: 
                <dtml-if text_error>
                  <font color="red">&text_error;</font>
                </dtml-if>
                <br><textarea name="text:text">value="&dtml-text;">

             <input type="submit">
          </dtml-form>
       </body></html>

    We could do this without a new tag. But the example wouldn't be so
    simple. ;)

    Zen -- This example will of course raise a KeyError, as the
     values for the input controls will not render during the 
     initial viewing of the form. The simple fix for this is to 
     add another attribute to the dtml-form, which specifies 
     a 'populate' object to populate REQUEST with required 
     values (eg. set them to empty strings, default values or 
     pull from a SESSION). We could also
     move the automatic variable type checking into 
     the &LT;dtml-form&GT; tag.

     For example::

        <html><body>

          <dtml-form post="main_post" validate="main_validate"
            populator="SESSION" 
            controls="title,text:text,priority:int"
            errors="errors,title_error,text_error">
           
            <p>main_post will only be called if neither
             main_validate or the Zope internal type checking
            (priority:int) returns any errors.

            <dtml-if errors>
              <hr><font color="red"><ul>
                 <dtml-in errors>
                   <li>&dtml-sequence-var;</li>
                 </dtml-in>                    
              </ul></font><hr>
            </dtml-if>

            Title: 
               <br><input name=title value="&dtml-title;">
            Priority:               
               <br><input name=priority value="&dtml-priority;">
            Text: 
               <br><textarea name=text value="&dtml-text;">
             <input type="submit">
          </dtml-form>
          </body></html>

    ChrisW -- I actually like the idea of the new tag. It makes               things nice and clean :-)

    The dtml-form tag:

    - generates a HTML form tag, using the request URL
      as the action. 

    - If the request method is POST:

      o Makes sure that REQUEST!['HTTP_REFERER']==REQUEST!['URL'], to
        protect against trojans. ;)

        Could this be optional? Could you supply a list of  
        acceptable referers? I can think of ocassions when it's 
        useful to have two seperate forms handled by the same 
        action.

        PJE -- not only that, but what do you do about clients which don't send referrers?  What about XML-RPC POST operations?  Maybe this should be implemented using different method names, e.g. GET and POST instead of index_html.  POST could call GET if errors are present.  No tags needed, cleaner seperation of functionality...?

      o Securely calls the method given in the post attribute,
        'main_post'. 

        Note -- We need a way of expressing that a method is
          callable by DTML but not callable through the web....
          And the other way around.

          ChrisW -- I suggested this on the ZopeDev list on 
                    11/12/99 as 'Execute permission thoughts...' 
                    but didn't get any response :(

          ChrisW -- This had another airing on the ZopeDev list recently (May 2000) and lots of interesting views were expressed. Maybe someone could pick one and implement it? ;-)

      o If the result of calling POST is None:
 
        - Adds the names mentioned in the "errors" attribute to the
          namespace with empty strings as values.

        Otherwise:      

        - Pushes REQUEST to the top of the namspace stack.

        - Adds the names mentioned in the "errors" attribute to the
          namespace with empty strings as values.

        - Adds the attributes of the result of calling POST to the
          namespace.

    - If the request method is GET:
 
      Adds the names mentioned in the "errors" attribute to the
      namespace with empty strings as values.

  I've been thinking of a facility like this for a while. What finally
  pushed me over the edge was Emacs W3 v4.0 whining about a redirect
  after editing a wiki page. Would this facility help? Hm. Well, not
  exactly. With Wiki pages, there are three pieces: 

    - The normal view

    - The edit view

    - The edit action

  Currently, you view the normal view, follow a link to the edit view,
  POST to the edit action, which redirects to the normal view.

  The POST would need to go to the normal view. If there aren't any
  errors, then we display the nrmal view with updated data. If there
  *are* errors, we would need to display the edit view with the
  errors. This might be a bit weird, although I think I could live
  with it.

  The implementation would be a bit different, since the normal
  view a Python method, not a DTML method.  Also, the HTTP_REFERER
  check would have to allow the normal view *or* the edit view.

<hr>

I just implemented a form in this way. Here's the code, as food for thought: GetAndPostExampleOne
--ZWikiWeb:SimonMichael
<hr>
JHT

I've done systems this way.  Works fine from the perspective of the web server, but not so well from the perspective of the user.
What happens is that a user fills out a form and submits it.
They get back the results and then go to the next page.
Now if they try to use the back arrow to see the results again, the browser wants to repost the form before it will display the page again.  The redirect scheme gets around this problem.