drupal
Keeping Drupal up to date
Drupal depends heavily on contributed modules to implement a lot of it's functionality. One of the benefits of this is that the system is very modular and it's easy to configure the proper set of functionality. On the down side, this can lead to module creep, where you install lots of modules that you don't "really" need because they do something cool. Among other things this can make keeping up with new module releases a pain.
Lately, I've been addressing this problem with a combination of drush and update_status. Drush is available for both Drupal 5 and 6, and update_status is a contrib module in 5, and in core for 6.
It's pretty straightforward. Update_status gives you an admin page (and can also notify you via email) displaying which modules you have installed, and if any of them have updates available, especially security fixes. Drush, on the other hand, is a command line interface to the Drupal system that allows you to manage packages from the command line (similar to apt-get on a Debian Linux system), run database queries, and other maintenance tasks (cloning database and directory trees, etc).
I install drush into sites/all/modules on a Drupal site and enable it in the system, including the Package Management, wget, SQL support, and toolbox modules.
Then, from the site root, one can run UNIX shell commands such as
php sites/all/modules/drush/drush.php pm update og
This particular example updates the organic groups module, which the update status page has informed me is out of date. Once I've updated the module, I run /update.php to apply any necessary database schema changes.
And that's pretty much it. I'd like to see automatic application of schema changes and automated rollback (so that updates are an atomic operation), and so on, but so far it has seriously reduced the overhead of bringing sites up to date. These two modules are the first that I add to any new projects I'm working on.
Migrating custom tables to Drupal nodes
In response to a discussion at the Sonoma County Drupal Users Group meeting this evening, I hacked up a quick example on how to migrate legacy data tables into Drupal nodes:
http://postcarbon.org/migrating_legacy_data_drupal_cck_nodes_example
Distributing modules with install scripts
So you've created the next great Drupal module that change the world, it works, and you're all set to go. But then you consider what it takes to get the module running, and realize it's nontrivial for an ordinary user to get things up and running. Most of the contrib modules that you can pull from Drupal.org don't have this problem; normally one plugs them in, enables them, and away you go (with the occasional exeption of a module which needs external code added by hand due to license restrictions).
I've run into this problem a couple of times, and yesterday I figured out how to set things up for installation. Modules are allowed to have modulename.install scripts which export implementations of hook_install() and hook_uninstall(), which are invoked on a module being installed for the first time, and being uninstalled.
In my case, I want to enable a new CCK type upon my module being installed. This means that the module requires both the Content (CCK) module and Content Copy (which is distributed as part of CCK). To make a note of this, I added both modules to my dependency list in my modulename.info.
dependencies = content content_copy
Now that we have the dependencies being enforced by the system, let's fill out our install hook, shall we? In this case, we are going to import a CCK type that I had previously created upon module installation. I grabbed the code for doing this import from Snipplr.
Here's the contents of my modulename.install file:
/**
* Implementation of hook_install().
*/
function modulename_install() {
include_once('./' . drupal_get_path('module', 'node') . '/content_types.inc');
include_once('./' . drupal_get_path('module', 'content') . '/content_admin.inc');
$cck_definition_file = './' . drupal_get_path('module', 'modulename') . '/ccktype_export.txt';
watchdog('modulename', "loading CCK type from $cck_definition_file");
$values = array();
$values['type_name'] = '';
$values['macro'] = file_get_contents($cck_definition_file);
drupal_execute("content_copy_import_form", $values);
}
My uninstall hook is empty for the moment, but I would imagine I should remove or disable my custom CCK type on uninstall.
Also, note that disabling a module does not uninstall it (nor run the uninstall hook). To uninstall a module you disable it, then go to the 'Uninstall' tab on the page and from there select the module for deletion. It turns out that even then, the module is not completely cleaned out from the system. To completely remove the module (and, it turns out, to get the install hook to fire on module enable), you have to go into the database and remove the module reference from the system table. I haven't had the chance yet to see if removing the line from the system table is an action commonly taken by modules in their uninstall hooks.
Porfolio Implementation
For the portfolio entries, I settled on using the CCK Slideshow module, which takes one or more images uploaded to a node using the Image CCK field, and renders them as a javascript slideshow which can be configured to automatically rotate images.
This ended up working quite well, and you can see the results on the portfolio page. This module satsfies some of the same requirements that I had for Mariska's Designs (still in progress), where individual products for sale needed image galleries. For that project, I hacked up a solution which rendered images uploaded as node file attachments as a flash-based gallery using the excellent SimpleViewer gallery.