Thanks to the diligent work of Chx, Eaton, Moshe and many other members of the community, we have made enough advancements with the Drupal
Forms API for the next release, that I have made the decision to call this release version 2.0. Apart from several fixes to the system, these developers have added features which allow us to do so much more with the API.

Read on for a description of what's new and what we are now capable of building.

The major upgrades

  1. Nodes are now rendered using a structured array and all the recursive rendering functionality of Forms API (including the powerful themeing features) are now supported for the rendering of node bodies.
  2. Make it possible to control access to form elements, which allows you to set the #access property on all form elements, including everything built using drupal_render(), such as nodes.
  3. Form definitions are now in their own functions, meaning form definitions can be 'pulled' by just using the form_id. This allows us to programmatically submit all forms.

Node rendering through drupal_render()

Having more flexibility with node output is self explanatory, but the biggest benefit of Eaton's work on node rendering is that the recursive rendering code that was written for Forms API, but which was was never intended to be directly form related, has now taken it's place as a generic way of building content. Also, use drupal_render() for profile display will introduce fapi like flexibility to profiles too. I believe that this will probably also make it into 4.8.

All the major features of FAPI are supported for things working with drupal_render(), including _alters and now the new #access property.

This layer will see even more polish with the next major revision of Forms API, to improve readability and make it simpler to build different views of content.

Drupal_render() now respects an access property for all elements

This means that we now have incredibly granular control over who is able to see information. Because nodes are also rendered through drupal_render(), and hopefully soon profiles will be too, you will be able to specify that certain user's aren't allowed to set x or y field in a node form, and some users are able to see more than what is visible to other roles.

Forms can now be programmatically submitted

All forms are now defined in their own functions, meaning that you no longer need to go to a certain page to build the form, and also that you can far more cleanly validate against drupal forms. The immediate benefits can be seen at :

The first patch allows us to drop Drupal into a 'recording mode', where all form submissions are saved to macros, which can then be replayed.
We will be able to use this to distribute things like CCK node types, etc in the future. My plans for FAPI 3.0 include giving macro recording enough
context that you can build your own macros for commonly run tasks, using a contrib module (e.g. on this node, add 5 points to the rating, promote to the front page, send a message to the user who owns the node saying they were added to the front page).

The second patch allows you to very simply build wizards, something which has been an issue with FAPI 1.0 since it's inception. It should even be possible to form_alter existing forms into becoming wizards, or just wrap the original form's functionality in a new form id (ie: add_node_wizard).

And there's more

There are several features that are not yet implemented in the roadmap for FAPI I have in my mind, and it is my hope that most of these will end up going into the next major revision FAPI 3.0, which I shall be discussing at DrupalCon in Brussels. We are much closer than we were to my original goals and I congratulate and thank everyone who was involved in making Drupal a far more powerful and flexible tool.

Comments

davidm’s picture

I assume the phrase "multipart forms" is not meant to clash with the traditional usage of that phrase. ;)

Is there a transition strategy from 4.7 to 4.8 forms? Can we plug in a 4.8 compatible library for use with 4.7?

Macro ideas are... interesting.. but think of the children! Will the structure of FAPI 2/3 for purposes such as macro recording be codified and enforced in some way? It seems to me another system is being invented, as a parallel to a standard API.

For example

on this node, add 5 points to the rating, promote to the front page, send a message to the user who owns the node saying they were added to the front page

Could perhaps more cleanly be enacted using a higher level API (it might not kill anyone to make this more object oriented). Validating the syntax of code is likely to be less messy and error free than that of form interactions... unless you choose to reimplement features of the programming language in the form structures (here we go again).

adrian’s picture

Actually.

The big issue remaining with FAPI at present, is that it mixes the model and the view, into one big hella mess of a nested array, using all kinds of things like the #tree property to extract the necessary info out of the form.

I am talking of splitting out the form array into 2 separate arrays, the 'model', and the 'view' (since view is used, we end up talking about 'structures' though). The model 'array' is actually far more akin to an object than not, and I even have constructors and other object orientated code in mind.
The model array will contain only the fields (which is vastly simpler when you don't have to worry about fieldsets and tree properties etc. blah).

The issue is that you need to have more context about what it is your are rendering / editing, and even if you use objects as the
storage mechanism, you end up requiring a lot of additional information about fields that php simply doesn't support, without encapsulating
every single thing in objects. If we had a clean way to define the object/array duality that simplexml uses, I would jump for it.

Another very clear issue for us is php's lack of namespaces, which we can approximate using coding standards of function names, but is harder when you get into object oriented territory. Like i could define a new view of a node , say an extended summary, for the node model, by simply defining a function. I would not have that freedom when using objects.

It all depends on how php's syntax works for the stuff we want to do. I will be discussing all of this at BarCamp, and will do some proper research about what this would all look like in an object oriented world.

There is forms upgrade documentation (on the upgrading your modules to 4.8 page). It is generally a very simple process.

--
The future is so Bryght, I have to wear shades.

davidm’s picture

The big issue remaining with FAPI at present, is that it mixes the model and the view, into one big hella mess of a nested array, using all kinds of things like the #tree property to extract the necessary info out of the form.

I think one of the real attributes of Drupal development is it doesn't take strict paradigms too seriously (and when it does, it's sometimes a bit precious ;)). In fact, this is a successful strategy, as Drupal (and PHP frameworks) do well compared to more complex systems because of their accessibility. Most very formal systems run across corner cases they can't address, and end up being clunky for it.... along with all the extra work to create distinct implementations.

Trying to make a more ridgedly structured system with proper encapsulation, while using PHP and the community as it is, may end up being a very painful process. Even some Java (which stands for rigid, overdesigned systems - although there are many language features that are sorely missed) frameworks encode model and view attributes (such as validation or formatting hints) in the same place.

If the model is being used in multiple systems, it makes sense to have a very clean separation, but I don't think that is usually the case in Drupal land. What might be the solution is specifying a high level "object" api, at the interaction level, and leave functionality such as forms pluggable so people can reinvent at will.

I don't know much at all about PHP oo features (I've only heard bad things, and am pretty happy with Java, so have stayed away) but with interfaces and other common faciltiies this should be possible, if things could settle down long enough to implement such a design.

Or just do a Java version of Drupal. ;) People have already got it running under the JVM. (some very relevant conversation there too, by the way).

adrian’s picture

If the model is being used in multiple systems, it makes sense to have a very clean separation, but I don't think that is usually the case in Drupal land. What might be the solution is specifying a high level "object" api, at the interaction level, and leave functionality such as forms pluggable so people can reinvent at will.

That's pretty much what I said. Currently we only know what a node is supposed to contain, due to which form fields have been added to it.
I want to remove that stuff from the 'forms' and make the forms and displays freely swappable based on what 'objects' it is busy viewing / building / manipulating.

--
The future is so Bryght, I have to wear shades.

moshe weitzman’s picture

your recorder can be used to audit actions taken on the site so one could know who submitted any given form. is a bit like watchdog() but works without a developer having to remember to call watchdog().

adrian’s picture

additionally, if we had the previously values, and the new values, we could even revert most actions. We'd have to write special code to un-create nodes etc, though, but it's a very interesting prospect =)

This is part of what the command pattern entails.

--
The future is so Bryght, I have to wear shades.