Portfolio | Contact

Automating Drupal module activation

When upgrading a large Drupal site between major revisions, I find myself doing the update over and over again. Since one site I maintain has 149 modules, and a few more that come packaged with other contrib that are not activated, I decided I don't want to click all those checkboxes every time I do a trial upgrade. While I could have probably come up with some way to just activate every module easily, I really wanted selective activation.

Thanks to Greasemonkey, a Firefox addon, I have automated the activation of all the modules I want.

First, make a list of all the modules you want to activate. You can do this by viewing the HTML source of your modules page and looking for the name of your modules in the form input fields named something like status[coder]. You'll just want the coder part. I recommend putting each module on its own line so if you change your mind on one module, you can just comment out that line.

var modules = new Array();
modules = Array(
// REMOVE DEVEL MODULES BEFORE LIVE LAUNCH
// Development
'coder',
'devel',
'reroute_email',
'cache_disable',
'simpletest',
// END DEVELOPMENT MODULES

// Core - optional
'help',
'menu',
'path',
'syslog',
'tracker',
'update',
// Other
'advanced_help',
'cvs_deploy'
);

The working part of the Greasemonkey script is a loop that examines the name of all the checkboxes on the page.

var chkboxes=document.getElementsByTagName('input');
for (var i=0; i < chkboxes.length; i++) {
  if (chkboxes[i].type=="checkbox" && in_modules(chkboxes[i].name, modules)) {
    chkboxes[i].checked=true;
  }
}

Then the part that finds the name of the module is similar to PHP's core in_array() function, with a change to wrap the status[] input array around the string of the module name you're searching for to activate. Remember, the name of each checkbox is actually something like status[coder], not just the module name as we have in the modules array at the start of the file.

function in_modules(needle, haystack) {
  var found = false, key;

  for (key in haystack) {
    if ('status[' + haystack[key] + ']' == needle) {
      found = true;
      break;
    }
  }
  return found;
}

The nice part about how this script works is that you can keep the same list of modules as you add modules back to your contrib modules directory during your upgrade. In the case of 149 modules, I have to activate them in groups when I add them back during the update.php process. First I activate and update core optional modules as a group, then cck, views, and workflow as a group, then two groups of the remaining contrib modules. I'm positive that I experience weirdness when activating and updating all 149 modules at the same time, especially with CCK widgets. Since in this process you're only checking the available checkboxes against a list of valid ones to check, there is no error if you have not yet added all the modules in your Greasemonkey array.

Best of all, you can be sure you're checking the correct checkboxes each time. Just be sure to make the included pages URL in your Greasemonkey configuration appropriate to your environment so you don't accidentally activate your development modules on your live site. It's a good idea to keep those development modules in a separate block for easy disabling when going to production.

The attached script should get you started with a long list of popular modules as an example.

Submitted by deekayen on Sat, 02/21/2009 - 1:19am

deekayen's blog | 1 attachment

Drupal developer toolkit

Drupal modules

Firefox addons

Development tools

Submitted by deekayen on Fri, 02/13/2009 - 2:09am

deekayen's blog

URL rewrite override in Drupal

Path alias configuration in Drupal 6Drupal 6 introduced a new automagical function for rewriting URLs output through most of Drupal called custom_url_rewrite_outbound().

The path module already gives you the ability to alias paths to different places, but only within the same domain. To redirect a path that has already been aliased, or to a different subdomain or different location altogether, adding custom_url_rewrite_outbound() to settings.php might be a solution for you. Since this is not a hook, it can only be used once per Drupal installation, which is part of why settings.php is a recommended place for it.

This code example will rewrite user, user/register, about, advertise, forum, and blog to other domains by changing the base_url by reference. Any URL on the site that passes through Drupal's core url() function will be rewritten, even if it was aliased by the path module.

<?php
function custom_url_rewrite_outbound(&$path, &$options, $original_path) {
 
$url_rewrites = array(
   
// Drupal core paths
   
'user' => 'http://users.mysite.com',
   
'user/register' => 'http://users.mysite.com',

   
// general information paths
   
'about' => 'http://www.mysite.info',
   
'advertise' => 'http://www.mysite.info',

   
// other
   
'forum' => 'http://forums.mysite.com',
   
'blog' => 'http://blogs.mysite.com',
  );
  while (list(
$key, $value) = each($url_rewrites)) {
    if (
$path == $key || $original_path == $key) {
     
$options['base_url'] = $value; // updated by reference
     
$options['absolute'] = TRUE;
      break;
    }
  }
}
?>

Submitted by deekayen on Thu, 02/12/2009 - 12:58am

deekayen's blog

Drupal shared database multi-site

Drupal allows you to run from multiple different databases by being creative with the use of the multi-site functionality built into core. Using multi-site in this method requires certain intentional design decisions.

Note, this method is no replacement for fault-tolerant redundancy through replication, but it will allow a difference of content management between a primary domain and subdomains with different priorities.

In this example, I will show how to run a single site through multiple different subdomains and setup a development environment separate from the live configuration. This site will have a www domain for edited articles, blogs for users, and forums as a free-for-all.

First of all, administration of each multi-site will be essentially independent from another with the exception of the user tables, because we will share accounts across the sites. The three tables you'll want to separate from the rest of your configuration are at least

You might as why not share the role and users_roles, but in this example, a content editor role won't have any usefulness on the blogs subdomain, neither will a forum moderator have a point administering blogs.

As part of this, there will be three subdomains: www, blogs, and forums, which means our database names will be

Your file directory structure will request primarily from www, meaning that will be the default configuration of your Drupal multi-site installation.

/root folder

So far to this point, it's a fairly standard installation of multi-site Drupal with sharing the tables, but it's hard to use multi-site in a local environment if you want to be able to test each of the subdomains, which will only respond to the domains set in the directory names.

Since you shouldn't check your settings file into version control, your local copy of the settings.php files will change the $base_url to something more local-ish.

$base_url = 'http://forums.mysite.local';

Then update your /etc/hosts file to have some new entries:

127.0.0.1 www.mysite.local
127.0.0.1 blogs.mysite.local
127.0.0.1 forums.mysite.local

Then make a symbolic link to each one of your multi-site directories so Drupal will be able to find the local domains and respond to them with the local domain settings.

/root folder

Your symlinks and settings.php files won't be in version control because you ignored them (right?), so you should be able to easily develop from a local multi-site environment without having to setup a fancy MAMP-like package to manage your virtual, local domains.

Submitted by deekayen on Thu, 02/12/2009 - 12:25am

deekayen's blog

DD-WRT print server configuration

When DD-WRT v24-sp1 was released, it advertised USB printer support, but I have been so skeptical that it would actually work, that I didn't even bother trying it until last night.

I followed the second set of instructions on the Printer Sharing wiki page which involve setting up a usb.startup file. After I rebooted the router, the print server was running according to ps and netstat, computers on the network seemed to be ok with connecting to it, and they would send it print jobs, but nothing ever printed.

I undid the usb.startup configuration and followed the instructions for using /jffs/etc/init.d/p910nd and it worked on my Ubuntu Linux and Windows XP machines. I haven't been able to get my MacBook to print yet, but that might be an unfortunate driver issue I can resolve by printing to another computer that's set to share the printer on the network.

Here's a quick re-cap of what I did at the DD-WRT commandline after I enabled JFFS and all USB support in the web interface except USB storage:

ls -la /dev/usb/ (should show lp0)
dmesg | usb (should list a printer)
ipkg update
ipkg -d root install p910nd
vi /jffs/etc/init.d/p910nd

Change the default path to DEFAULT=/jffs/etc/default/p910nd

Add /jffs/etc/init.d/p910nd start to the startup scripts through Administration/Commands in the web interface

/jffs/etc/init.d/p910nd start
netstat -an | grep 9100
ps | grep p910
cd /
umount /jffs
reboot

Submitted by deekayen on Fri, 02/06/2009 - 11:29am

deekayen's blog
Syndicate content

recreation