[development] FormAPI 3 has landed

Jeff Eaton jeff at viapositiva.net
Tue May 15 08:58:32 UTC 2007

For the last several weeks, chx, myself, and a number of others have 
been working on a large set of improvements for FormAPI in Drupal 6. 
(http://drupal.org/node/138706 is the issue in question)

The vast majority of these changes revolve around simplifying FAPI's 
weird edge cases, making the system more internally consistent, removing 
roadblocks to things like AJAX forms, and applying some of the lessons 
we learned in previous iterations (making multistep work cleaner and 
smoother, etc).

One of the biggest changes is the introduction of the 'form state' 
variable. Previous versions of FormAPI used a combination of 
$form_values, global variables, and custom flags in the form definition 
itself to capture information about the form's workflow and its current 
state during processing. In Drupal 6, a single array -- $form_state -- 
is passed along through each stage of form processing. It contains all 
the state information and contextual flags needed to control the form's 
processing and workflow. Among other things, this has enabled us to 
completely eliminate the use of globals in form.inc, and -- with the 
exception of edge cases involving batch processing -- we no longer 
clutter up the session with form state information.

The consistency of the form state also variable means that we can use it 
to eliminate a number of diverse (and weird) techniques for passing data 
around and controlling flow. Validation handlers can pass data on to 
submit handlers, submit handlers (be setting $form_state['rebuild']) can 
trigger a multistep-style revisiting of the form. Submit handlers place 
their redirection paths in $form_state['redirect'] rather than returning 
a text-string. Node creation forms can populate $form_state['nid'], 
which is returned to drupal_execute when its called in that context.

Submit handlers can set the $form_state['rebuild'] flag to indicate that 
the form should be rebuilt, multistep-style, rather than being cleared 
out. When this happens, all the information in $form_state, including 
the current post/form_values data, is fed back into the form constructor 
function. If the form handling requires transient data (like partial 
answers to a survey) to be built up in multiple stages before 
permission, handlers can use the $form_state['storage'] bin, which 
FormAPI caches between page-loads to preserve for the entire lifetime of 
the form.  (Developers no longer have to carry the burden of figuring 
out where to store all their 'in progress' form values, hide them in 
unvalidated hidden fields, etc.)
In addition, behind the scenes we're also using a new dedicated cache 
table for forms -- in multistep scenerios where forms must be built once 
for validation and once for rendering, we're caching the form definition 
array and retriving it for the validation stage rather than forcing it 
to be built twice. The fact that we're storing that array structure also 
opens the doors for AJAX and AHAH forms -- callbacks on the server could 
open the cached form array and alter in fields that have been added on 
the client side, so that when validation time comes everything matches 
up. While that AJAX integration is not explicitly built into FAPI, the 
new cache-based multistep system makes such change possible.

There are MANY changes and improvements. Fortunately, few require much 
more than changing a function signature. But all Drupal developers are 
encouraged to visit the upgrade documentation page at 
http://drupal.org/node/144132 -- there are likely to be LOTS of 
questions, and that first stab at documenting the changes is only round one.

Feedback is much appreciated!


More information about the development mailing list