Building a Drupal module from scratch can be remarkably simple -- just create an .info file, create a .module file, then implement a few functions like hook_menu and hook_nodeapi. In no time, you've got a module up and running, leveraging Drupal's APIs and adding functionality to your site.
Unfortunately, things can get a bit more complicated if your module needs to store and maintain its own collection of data. The Custom Links module, for example, allows users to add clickable links to the bottom of each node on a Drupal site. While the code to actually add the links to each node is only a few dozen lines of PHP, it takes a few hundred lines of code to store and manage the information about those links. The module needs to create a database table to store its records, provide management pages so an admin can add new links, manage permissions, handle adding and editing records, request confirmation when administrators delete a record, and so on.
This pattern appears over and over in many Drupal modules. None of these tasks are horrible in and of themselves, but they add up to a lot of code, and a lot of special cases to overlook when you're busy focusing on the real functionality of a new module. And while Drupal.org provides a a large selection of example modules that demonstrate the use of various APIs, none of them provide skeleton code for these common, repetitive back-end maintenance tasks.
None, that is, until now. Inspired by yet another evening of copying-and-pasting administrative UI code and trying to remember all the special-cases, I decided to clean up the 'template' code that I keep lying around for these situations, comment it thoroughly, and bundle it up as a re-usable example module. Angie "Webchick" Byron helped pore over the resulting code and made improvements to the style and documentation... and the result -- Scaffolding Example Module -- is now available for download on Drupal.org.
Who Shot Who In The What, Now?
What do you get when you download Scaffolding Example module?
- Uses Drupal's Schema API and an .install file to define a custom database table.
- Provides an example update hook, to give users of your module an upgrade path if the database schema changes.
- Implements load/save/delete functions for the module's data.
- Demonstrates the use of Drupal 6's new drupal_write_record() function, to generate hassle-free insert and update SQL.
- Demonstrates the use of a Menu API 'auto-load' function, new in Drupal 6.
- Provides a 'batch' loading mechanism for all records, with notes on when and where to add caching if your module needs a performance boost.
- Provides permissions and user access checks to keep out non-administrators.
- Provides an overview form that uses Drupal 6's new drag-and-drop system to reorder records in a table.
- Provides a dual-purpose add record/edit record form.
- Provides a standard confirmation form to delete records.
- Demonstrates Drupal 6's custom button callbacks, allowing each button on a form to trigger a different function when it's clicked.
- Uses swanky little edit and delete icons -- GPL'd icons, at that.
- Provides a simple listing page to display all records.
- Provides a simple themable function to render a single record..
In addition -- and this is the important part -- it does all of these things 'the Drupal way,' using standard API functions and presenting information in a way that's consistent with the rest of Drupal's core interface. An example is the confirmation form that's presented when an administrator deletes a record. I'm always forgetting the bits of syntax needed to use it properly, but using this Scaffolding module, the hard work is already done.
Is there a catch?
Two caveats are in order. First, you'll still need to replace the 'example' portions of the module with your own code. Chances are, you want more than the 'title' and 'content' fields the module keeps track of. Changing hook_schema() to set up the columns you need, and changing the add/edit form to manipulate them, is still in your court. Second, Scaffolding Example doesn't do anything with the data that it manages. It's up to you to build something on top of it, whether that's spitting out XML files, changing the site's breadcrumbs, or curing cancer.
Finally, there are portions of the code that may be unnecessary for you -- if your module's data doesn't need a 'weight' field, for example, there's no need to add the Drupal table-dragging code. That's a small tweak to the theme function, though, and is clearly marked in code comments.
Go west, young coder!
Scaffolding Example module obviously can't solve every problem. But it does make it easy to fly through the 'grunt work' of building a simple administrative interface for your module. Download it, check it out, and if you can think of other improvements, post your ideas and your patches on Drupal.org!
Update: Shortly after publishing this article, several people jumped in and contributed code to make the Scaffolding module even better! Be sure to visit the Drupal Developer Examples collection for the latest version of Scaffolding module's code.