This is a meditation on processing data from HTML forms. There is a page at the Perl 5 wiki on that subject - it is a more practical list of available form processing libraries, here I wanted to ponder a bit more theoretically on that subject (and perhaps later update that other page).

What form processors do:

  1. Parsing the CGI parameters and constructing internal version of them. This might be basic (only parsing), through constructing a simple data structure (for hierarchical params - like param.subparam etc) to constructing objects (for dates).
  2. Validating
  3. Saving the values to the persistance layer (database)
  4. Loading values from the persistance layer for point 5
  5. Generating HTML (with error indicators etc).
Not all form processors need to do all of those parts (many don't generated HTML). And there are questions:
  1. Should the HTML be generated? I think it is useful as a 'first stage' approach. The logic of adding the error messages and inserting appriopriate error CSS classes is quite complicated so this saves a lot of work. But there should be also left a path for upgrading to using external form templates with the library - so that later, when the project grows the designers can use some more fancy constructs.
  2. Should validation be done on the internal representation (objects) or on the key value pairs from the first parsing? If it is done on internal representation - then how errors are supposed to be propagated to the HTML generator (which works on the key value pairs)?
  3. How to interface with specialized data validating libraries?
  4. When form should be saved to the database? Obviously only when it has valid parameters - but some people also check the HTTP method and other things.
  5. When values should be loaded from the database? Only if form is not submitted - but I also like to pass values to a form from a link - so I would like if it would not overwrite it with values from the db.

Replies are listed 'Best First'.
Re: Form Processing
by moritz (Cardinal) on Mar 25, 2009 at 10:03 UTC
    If it is done on internal representation - then how errors are supposed to be propagated to the HTML generator (which works on the key value pairs)?

    By having a bi-directional mapping between the internal representation and the key-values pairs

    How to interface with specialized data validating libraries?

    Callbacks might be a solution

    When form should be saved to the database? Obviously only when it has valid parameters - but some people also check the HTTP method and other things.

    IMHO saving things to a database is not job of the form processor. It could create objects that can be stored into the database with a single method call, but it shouldn't do it - that's the job of the controlling method that called the form processor in the first place.

    When values should be loaded from the database?

    Same answer as above.

    IMHO a form processor shouldn't talk to the database at all, at least not directly. For example the callbacks that validate input data could talk to the database, but having a form processor do that seems like over stretching its task.

    Could it be that you have a full CRUD framework in mind, not just a form processor?

      Ad. 'talking to the database'. I think I partially agree - and indeed I've wrote DBIx::Class::ResultSet::RecursiveUpdate exactly for the task of saving the data that I get from form processors (originally for FormFu, later Rose, and now I think about HTML::FormHandler, thanks to having it separated I can change the form processors quite easily). So the form only generates an update hash (or a more complex structure of hashes and arrays) and it is saved to the db by this specialized module. But still on the form processor there is always that ->save_to_db (or ->process) method which asks RecursiveUpdate to do the saving. It is just convenient.

      And in the other direction - it is the same thing, you need to walk all the form nodes and convert the internal objects into the field values - what else could be better suited for that task than the form processor itself?

Re: Form Processing
by Anonymous Monk on Mar 25, 2009 at 13:29 UTC

    In a world of “TMTOWTDI,” it is impossible to characterize form-processors. Different modules have been designed with different scopes.

    For example, HTML::FormFu, as its name implies, offers everything. It's a “cradle-to-grave” solution, and if you happen to need many hundreds of data-input forms and subforms, all closely tied to underlying database structures (and especially if those structures are changed frequently), you can exploit this module in just the way(s) that the designer intended.

    Even so, there are numerous ways to get there. Form creation, data collection from the HTML input-stream, validation and cross-validation, and HTML output are all separate processes, and so, “they can be separated, or not.” You don't have to use everything that a package offers you.

    In my most-recent application, for example, I did things quite differently. I used HTML::FormHandler to define input-forms, in the sense that they are “a means for capturing POST-inputs and validating them.” The generation of all the screens is done with the venerable Template::Toolkit. However, in a few cases I do avail myself of HTML::FormHandler::Render::Simple. Since all of my applications' data is stored in persistent Perl objects, the form-handler's data model layer has been customized to do that ... and to capture and interpret any exceptions that may be thrown by the objects when they refuse to accept what they have been kindly offered.

    One of the very useful services that a form-handler provides is, of course, validation and therefore error-message generation, but it's up to you what (if anything) you actually do with that message. A form-field will provide you with the basic ability to discover whether or not it “is valid,” or “is empty” and so-forth, or that it “has an error.” Other higher-level functions will use this to produce an error-message, if you choose to employ those higher-level functions in your app.

    It is important to remember that form handling and HTML templating are not the same concern. In my case, for example, just about every page of the application wraps its entire content in a <FORM> tag... but that's just how the templates are designed.

    Final comment:   at the very bottom, the most-basic foundation, we still have the venerable CGI module, which is a rock-solid way to interpret an HTML data stream. As far as I know, just about everyone uses it.

      #%@#%!!” ... forgot to log-in again! Anyway, “that's my post.”

      I certainely agree that this is a very foggy area - and most probably you are right that one cannot make a strict definition of form processing that everyone would accept. But in my view this is exactly what makes it an intersting discussion subject :). I thought it would be enlightening to gather all the opinions (and here I need to thank you for yours :).
      By the way - you might want to join the FormHandler mailing list or show up at #formhandler on to discuss its future changes.