Home

Lullabot

Lullabot Ideas

We know stuff. We empower you to know stuff too.

Drupal Module Development Deep Dive Week

London, UK
September 20-24, 2010

Module-In-A-Box: We Built Admin Tools So You Don't Have To

Article by Jeff EatonJune 1, 2008 - 2:57pm

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.

The problem

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.

Screenshot of boring, repetitive codeThis 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.

Screenshot of Scaffolding Module's administrative overview page

Who Shot Who In The What, Now?

What do you get when you download Scaffolding Example module?

  • CRUD
    • 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.
  • Administration
    • 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.
  • Presentation
    • 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.

Screenshot of Scaffolding Example's edit and confirmation pages

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.

Comments

Wim Leers (not verified) on June 1, 2008 - 5:29pm

Thanks Eaton, and thanks

Thanks Eaton, and thanks Lullabot! :)

I have yet to write my first line of Drupal 6 code. University is to blame for the lack of time. But I'm sure this will be helpful in getting up to speed with Drupal 6's APIs fast!

Morbus Iff (not verified) on June 1, 2008 - 6:36pm

The .install file doesn't

The .install file doesn't follow the new major/minor version numbering format for update functions. See http://drupal.org/node/114774#update-n.

June 1, 2008 - 7:21pm Jeff Eaton

Thanks!

The .install file has been updated in Drupal's CVS repository and in the .zip file attached to the article.

Anonymous (not verified) on July 30, 2008 - 12:16pm

I don't see a zip file

I don't see a zip file anywhere attached to this article

Addison Berry on July 30, 2008 - 1:21pm

Check out the Update

The update at the bottom of the article explains where the code's permanent home now is.

Josiah Ritchie (not verified) on June 1, 2008 - 8:02pm

Thanks :-)

Thanks Eaton! What a great gift to get things moving for more Drupal creative goodness.

theBorg (not verified) on June 2, 2008 - 12:45am

Thanks!!

You gave us the bread, now we put some meat into and we've got a del.icio.us Drupal sandwich.

Very nice idea!

psynaptic (not verified) on June 2, 2008 - 3:48am

Spooky

I was just thinking yesterday of creating some template modules to give away on my blog and you've beaten me to it! Admittedly, my templates would be very basic compared to this. Thanks a lot for sharing your super ninja skills.

yaph (not verified) on June 2, 2008 - 5:28am

Thanks for sharing this

Thanks for sharing this code. It does not only reduce the work for developing a new Drupal 6 module but also helps getting to know the API changes.

pwolanin (not verified) on June 2, 2008 - 7:18am

Object Driver overlap?

Hi Eaton,

I haven't updated this for 6.x yet, but there seems to be some overlap - my idea was to enable CRUD and some basic UI via having a second module that defines the scema and optionally some hooks, while the main module handles getting stuff into and out of the DB for any number of such add ons.

http://drupal.org/project/object_driver

Maybe we should put our heads togeter.

xamox (not verified) on June 2, 2008 - 9:28am

Zen module! Nicely done

Zen module! Nicely done Jeff.

Chris Charlton (not verified) on June 2, 2008 - 4:02pm

Time for a template

Sweet! I just did Eclipse code templates for Drupal modules/stub code and I will be taking this module code and making a new set of templates. Shall I share?

June 2, 2008 - 4:45pm Jeff Eaton

Absolutely!

That would be fabulous. I'm in the process of converting the module to a Komodo template, too. One important note, though -- the file that I originally attached to this article is already out of date. Since the module was uploaded to Drupal.org, folks have already started improving it. http://cvs.drupal.org/viewvc.py/drupal/contributions/docs/developer/exam... is the place to get the latest and greatest version. Thanks!

Ken (not verified) on June 30, 2008 - 4:01pm

getting an error on install

This looks fantastic! I need a way to dynamically integrate items of content from an external source, and this looks like it will save a whole bunch of time for me and learning curve. Unfortunately, after uploading the module files to site/all/modules and then going into Module Admin and enabling it, there's a long pause and then I get a 500 error. Any idea what might be happening?

Ken (not verified) on July 2, 2008 - 9:00am

mystery solved

One of the module files I downloaded got entity-encoded somehow, so less-than/greater-than signs and ampersands were throwing parse errors. I discovered this after coming across a post that suggested checking the Apache error logs, which spelled it out pretty clearly. Yes, I'm a newbie. :-)

Peter (not verified) on July 24, 2008 - 12:25pm

Paged List tab

Great module, downloaded and runs OK. Just what I need.

Except for paged list tab. (Drupal 6.3)

Is reporting an error as below

warning: Invalid argument supplied for foreach() in C:\Apache229\htdocs\drupal63\includes\theme.inc on line 1289.

Have reduced limit to 2 for testing, entered say 10 records and still develops error. Header block and paging navigation does work OK, but where listed themed content shows the above error.

Any ideas what could be causing this please?

Eric (not verified) on August 15, 2008 - 11:51am

Paged List tab

Thanks for this module, it's a great way to reduce the time it takes to develop this pattern. Found this because I was looking for something similar to the scaffolding system used in Ruby on Rails for Drupal.

As for the bug, I found that it's due to the way the rows are added. It's not using the 'data' keyword.. here's the code and I commented out the old method and added my own.

<?php
 
while ($record = db_fetch_array($result)) {
   
$rows[] = array( 'data' => array(
     
check_plain($record['title']),
     
check_plain($record['weight']),
     
_scaffolding_example_record_links($record)
    ));
   
//$rows[] = check_plain($record['title']);
    //$rows[] = check_plain($record['weight']);
    //$rows[] = _scaffolding_example_record_links($record);
 
}
?>

MattW (not verified) on September 3, 2008 - 11:38am

Thank you so much!

Just want to say thanks I ton. I am currently upgrading my Visual Basic Source site to Drupal 6.0 and I need to create some custom modules to display my tutorials and source samples. Your sample module has helped me a ton as I enter into this development endeavor. Thank you so much and keep it up!

yammy (not verified) on September 23, 2008 - 4:17pm

this module doesn't install in drupal 6.4

I loved the scaffolding idea, but I created the module folder here, but drupal admin says it's not compatible with drupal 6.4

=(

I see no zip file here either, it would be great to have a 'last version zip' instead of copying each file, then renaming each from .txt

thanks!

sklepy internetowe kraków (not verified) on November 23, 2008 - 2:20pm

module doesn't install in drupal 6.4

This looks good! Really good tutorial include so many helpful informations!

chlorophyll (not verified) on November 29, 2008 - 11:58am

Paged List tab

Great list, it helps clear up much of the htacess mystery and confusion that comes from creating such files.

Anonymous (not verified) on December 21, 2008 - 5:04pm

Needs to be maintained

Great demonstration module and good article but the module and article needs to be maintained.

It is currently December, four months after Eric (in the comments above) discovered an error in the code and gave the corrected code. This still hasn't been added to the code in CVS.

The documentation also needs to tell people what to do with the image files. I expect most people are like me and expect to download and run the program first and only after doing so would they start examining the code to see how it was made. In order to do that they need to know what to do with the two images that you download from the CVS. A note like the following is needed.

"Implementers have to create a directory, rename it scaffolding_example and download from the CVS into this directory each of the files (scaffolding_example.admin.inc, scaffolding_example.info, scaffolding_example.install, scaffolding_example.module, scaffolding_example.pages.inc ) being sure to name each file correctly.

Within the scaffolding_example directory create a sub directory named images. Download the two images into this images directory, keeping their original names (edit-delete.png and text-editor.png). (ensure that you have got the actual images by viewing them after download)

Upload the full scaffolding_example directory into the sites/all/modules directory on your Drupal 6 installation. If you don't have a modules directory within sites/all then create it.

You should now be able to go to the administration >> modules menu item of your drupal installation and enable this new module"

Hope this helps

Ken
http://www.ausvalue.com

cornice (not verified) on December 27, 2008 - 11:52am

Paged List tab

Thanks for this article, it's great. So great that we've made it 'sticky' on The Webmaster Forums. Now we don't have to repeat ourselves, just send people to this article!

Pete (not verified) on March 17, 2009 - 9:06am

Drupal 5?

Do you think you could adapt this to Drupal 5, please?

And, if you're not going to do that - any pointers to how I can adapt it to Drupal 5 myself?

Anonymous (not verified) on May 14, 2009 - 3:56pm

A big help to new folks

I'm using this to teach myself drupal programming and it's great. One addition that would help me, is field validation. Where would I put logic to validate the contents of a field? How do I return the error to the user and prevent the update?

About this 'bot

Jeff Eaton

Jeff Eaton is a long-time web developer. He's been designing, administering, and implementing web projects since he pieced together his first HTML file in 1996. He's built ecommerce sites for florists, helped implement enterprise web systems for multinational corporations, and juggled web architectures from legacy Perl to ASP.Net. (With some Windows desktop development thrown in for good measure...) Yes...

more

Recent

Drupal Voices 160: Moshe Weitzman on Page Rendering in Drupal 7

Podcast 9.02.2010

Drupal Voices 159: John Albin Wilkins on Drupal 7 Theming

Podcast 9.01.2010

Drupal Voices 158: Emma Jane Hogbin on PHP for Designers

Podcast 8.31.2010

Command Line Basics: More Editing with Vi/Vim

Video 8.31.2010

Lullabot's Back to School Sale

Blog 8.30.2010

Popular

Drupal Voices 160: Moshe Weitzman on Page Rendering in Drupal 7

Podcast 9.02.2010

Photo galleries with Views Attach

Article 6.01.2009

Drupal Voices 159: John Albin Wilkins on Drupal 7 Theming

Podcast 9.01.2010

Announcing BeautyTips, a jQuery Tooltip Plugin

Article 10.20.2008

Install a Local Web Server on Ubuntu

Video 11.14.2007
 
  • Home
  • Services
  • Events
  • Ideas
  • Store

Connect the Bots:

Twitter Facebook YouTube blip.tv All Posts Newsletter
  • Ideas
  • Blog
  • Podcasts
  • Videos
  • About
  • Contact
  • Jobs
  • Services
    • Training
  • Events
    • Training Workshops
    • Other Events
    • Conferences
    • Calendar
  • Products
    • Videos
    • Books
    • Swag
  • Ideas
    • Blog
    • Podcast
    • Videos
  • About
    • Philosophy
    • Team
    • Presskit
  • Contact
    • General
    • Work Inquiries
    • Mailing List