Presently, drupal_get_form() is an all-or-nothing affair. You call it and it builds, validates, submits, and (if applicable) renders the form and returns it as HTML.
This causes problems, though, when forms are to be used in other processes or when forms must submit to themselves multiple times and dynamically change their contents. This patch splits the actual rendering of the form as HTML into a separate function. drupal_get_form() also gets a new optional paramater: $render. It defaults to true, but if it's set to false the function will return the raw form array rather than its HTML representation.
I'd like to split the building (including form_alter hook calls), the validation, and the submission portions into their own separate functions as well, allowing modules that need full contorl over the process to bypass drupal_get_form() entirely, but... baby steps.
Reviews would be much appreciated.
Comment | File | Size | Author |
---|---|---|---|
#10 | form.inc_30.patch | 8.17 KB | eaton |
#8 | form.inc_29.patch | 8.17 KB | eaton |
#7 | form.inc_28.patch | 7.85 KB | eaton |
#6 | form.inc_27.patch | 4.47 KB | eaton |
#2 | form.inc_26.patch | 4.91 KB | eaton |
Comments
Comment #1
eaton CreditAttribution: eaton commentedHere's a patch that *does* split out drupal_build_form(), allowing all the form altering and addition of necessary properties like #form_id to occur in a separate function. This will make it much, much simpler to create dynamic forms.
drupal_get_form() is now basically a wrapper for logic, and the relatively complex redirection handling. In cases where modules have to do very complex things with forms (wizards, and cases like views.module come to mind) it is now possible to sidestep drupal_get_form entirely and control the flow of form building and rendering without reimplimenting ~100 additional lines of essential code.
Yay.
Comment #2
eaton CreditAttribution: eaton commentedAnd finally...
After some IRC discussions with chx, Vertice, and clouseau, a third version.
In this patch, drupal_get_form() is back to its original parameter list. However, all the meat of it is split out into separate functions:
drupal_build_form()
drupal_validate_form()
drupal_submit_form()
drupal_redirect_form()
drupal_render_form()
*no* existing behavior is changed, but modules with special needs and complex form based workflows can use those separate functions to bypass drupal_get_form() entirely and do their business as needed. drupal_get_form() would serve as the 'easy' way to display forms, and a reference implementation for those that need to build them in more complicated ways.
Comment #3
adrian CreditAttribution: adrian commentedI am all for more granular code.
Not sure I like the extra parameter added.
Comment #4
eaton CreditAttribution: eaton commentedAdrian, I've see the light on the extra parameter. the latest patch in this series eliminates that. With this patch, modules that need custom flow handling would just bypass drupal_get_form() entirely and do their thing.
With things broken out this way, doing so would still be reliable and safe -- there would be no need to duplicate the API's existing building/rendering/etc functions.
Comment #5
moshe weitzman CreditAttribution: moshe weitzman commentedwhats not to like? as long as it doesn't break anything, +1
Comment #6
eaton CreditAttribution: eaton commentedMissed a change that went in yesterday (a clarifying comment in the rendering code). Added that and re-rolled.
Comment #7
eaton CreditAttribution: eaton commentedNow with doxygen comments. Since the sub-functions are now acceptable for use by other modules, documenting them is a good thing.
Comment #8
eaton CreditAttribution: eaton commentedTweaks to the docs based on responses from chx and clouseau on #drupal. Thanks!
Comment #9
Dries CreditAttribution: Dries commentedLooks good to me. Marking this RTBC. Will commit unless someone objects. Updating version to 'cvs'.
Comment #10
eaton CreditAttribution: eaton commentedAnd... one more quick fix. I wasn't passing $form into drupal_redirect_form(), which obviously broke redirection.
Comment #11
webchickI think this was meant to be marked RTBC
Comment #12
Dries CreditAttribution: Dries commentedCommitted to CVS HEAD. Thanks.
Comment #13
(not verified) CreditAttribution: commented