A Drupal module is effectively a unit of DRY code. It’s a self-contained codebase that can be installed in any Drupal site. Additionally, modules can define theming hooks and Drupal blocks, which provides for a unified interface to your backend code. Most of the sites that I’ve worked on over the past year have some sort of header navigation. Sometimes it provides multi-level navigation through floating menus, sometimes it’s just top-level menu items, but really, the structure of the HTML is usually the same. The implementation usually follows a very similar pattern — store menu links in the Primary Links menu set, write some code to retrieve the menu links from the database, and then structure HTML in a hierarchical pattern for theming. The theming, though, is really the only thing that differs widely. Instead of doing something very similar in slightly divergent ways, it makes a lot more sense to just do the same thing the same way. So eventually I created a module that did just what I’ve stated above — and it’s one of the first modules I’ll install in any given project.
The even greater advantage here is that sometimes, when I start working on a project, I’ll realize that my code doesn’t really work. It’s not that it’s broken, it’s just that it’s missing features, or theres some fringe case where the code doesn’t quite work right. If a feature needed to be added, or a bug had been discovered, on a non-unified codebase, that would mean making changes to code in all the sites that used similar code. But when the same scenario occurs on a codebase that is 100% unified, I can make that change once, and just deploy that module to all the places it’s needed.
The only real pitfall here is that you do have to be careful to generally-case your code. You can’t make assumptions as to the environment you’re working in because that’s precisely what you are trying to avoid here. You want similar code to be the same — and where there needs to be different execution, you want to build that in as an option of your code, not a one-time, in-place change. Using that example of the header menu, I mentioned that the levels to which the header menu is tiled out is often different. Sometimes, it’s all the top-level menu items with no children. Sometimes, it’s all the children, or just first-level children. That’s really a small detail of the implementation of the code though. Sure, I could merely create 2 different modules for this, but even that means more maintenance work for what is, ostensibly, the same base functionality. The main way that I interface with this module is through a theme call in the theme’s template files. Something like theme(‘header-menu’). So why not just pass in an option for how I want the menu to work? theme(‘header-menu’, 0) for just the top level, or theme(‘header-menu’, 1) for top level with first level children? It takes a little foresight and a little more work on implementation, but by allowing for flexibility in the module means less complexity in the theme and better future-proofing of your codebase.
Features is a Drupal module which exposes additional functionality in the modules that you create. Basically, what it allows you to do is set variables and export views and CCK content type definitions for storage in your module. Imagine extending reusability from site elements like navigation and sidebar blocks, to entire sections of your site. Many sites have a blog section, which comprises a Blog Entry CCK type and a view or two for listings and some taxonomy definitions for your content. Well, Features lets you export all that functionality into a module which you could then import into any other site you work on. Even better, while we don’t want to override module code in order to keep a coherent codebase, the Features functionality has a bit of a different premise. If you focus on building a good base set of functionality, really, the point from then on is to extend that base to fit a particular site’s needs. Features expects this behavior and really focuses on allowing easy overriding of that base set of CCK types, views, taxonomy, etc.
These are two simple, big ways to start thinking about how your code should be structured in order to avoid repetition and deliver solid, full-featured functionality when you’re working on many Drupal sites. Modules are essential to taking advantage of a lot of what Drupal offers under-the-hood, but they’re also instrumental in extending DRY concepts in your work within the Drupal project. Features is a relatively new development which allows you to go even further with modules, and can let you scope out entire site sections simply by installing and enabling a module. The first site you work on, a lot of the value I’ve discussed here might not be readily apparent. But give it a try, and when you start that next Drupal site, you’ll be surprised just how much you get right off the bat, with little to no additional effort.