This is a collection of small tips and tricks for setting up your Drupal site. I'm keeping this primarily as a "reminder" for myself, but I'm guessing it might be useful for others too.
I've been using Drupal (v4.x and 5.x) for quite a while now. I've postponed the upgrades to 6.x to wait for stability, but more important, make sure all the additional modules I use become available for v6.x. Don't get me started with the annoyance that Drupal keeps breaking module compatibility between every major release, it'd be so nice to finalize these APIs at some point. In any case, I finally decided to go ahead and start migrating from v5.14 to the current Drupal 6.8 release. And this is an attempt to document the successes, failures and problems that I encoutered.
Before you do anything else, make a backup of your database. Don't skip this step, you will most likely regret it.
One important thing to do before upgrading is to make sure the old Drupal system is completely up to date. Make sure you have installed the latest Drupal 5.x version (currently 5.15), and that all modules you use are up-to-date (using the Update Status tool would be a good idea now). You might also want to consider upgrading modules that have major updates for both v5.x and v6.x, so that you use the latest versions (APIs) etc. with Drupal 5 first. Also remember to re-run the /update.php script after you do all these upgrades, to assure the database is completely up to do. It might be a good idea to run it at least twice, to make sure all changes are taking effect (and obviously look for any errors and warnings).
After running all the upgrades, disable all third party modules that your site is doing. This is a critical step, as I found out several modules do not handle a massive upgrade at all (for example, CCK). Disabling these modules assures that during the first upgrade steps, you do not force Drupal to do all upgrade changes in one attempt. I don't know why this makes a difference, but trust me, it does.
Since I run multiple Drupal sites, I decided to install Drupal 6.x in parallel with my old installation, this allows me to migrate one site at a time. In order to make it even easier to do this safely, I actually duplicate each site first, making a mySQL copy of the entire database, and a new DNS entry. This will posibly require a small change in your site config (for the base-URL), but it's a small price to pay. In particular, this lets me see how the old configurations were done and compare that to the "new" site after the upgrade. In my case, I had a site, http://www.boot.org/, the new site was temporarily named http://www6.boot.org/. Once the migration is finished, this obviously goes away, and I deleted the old database.
Install the modules you need, either now, or one by one. Remember, Drupal 6 will need all new versions of all external modules. As long as you have them disabled in the site, it should be ok, but if you want to be extra careful, don't unpack these modules yet (just get the tar-balls in preparation). If you are using a third party theme, make sure to install the new version of it. If not, make sure you switch the default (and/or admin) theme to one that is included with the base Drupal 6 package.
This is the easiest part, and I had no problems with this step. Assuming you've got your Apache configured properly for the new Drupal system, just go to the base URL, and append /update.php. Note that this has to be done as the privileged user (the first account created), unless you modify the script (not recommended). After the upgrade, verify the modules settings, configurations, ACLs etc. that they are still correct.
There is one huge caveat: Even though you (hopefully) have disabled all the 3rd party modules in the prep stage, you must delete the modules from the doc root. This really, really sucks, but I've noticed that the upgrade will kick in for some modules even when disabled (for example, Image does this nonsense). Since I now have many Drupal 6 sites, this means I have to duplicate my Drupal installation into yet another docroot during the upgrade, so I can remove all the modules, and add them back one by one. This is extremely annoying...
I use the CCK module extensively, and this part of the upgrade is what caused me most problems. My first attempt to upgrade failed, because I didn't follow the instructions to disable all external modules before doing the upgrade. This caused the CCK upgrade to partially fail, in particular three content field types did not get migrated properly. They all showed up with errors saying the module needed were not available or activated, but they for sure were. I could recreate new versions of the fields with no problems. After restoring the DB, and started over from scratch, I followed the instructions, and things worked a better. The content field based on the Fivestar module still shows up as inactive, because it claims some module is missing (which it isn't). I have not yet figured out how to solve this problem... Here's what I've tried so far, which at least lets me delete the field, and recreate it with the same name / configs (which preserves the data already stored in nodes):
thor $ mysql -u foo -p
mysql> update content_node_field_instance set widget_active=1 where widget_active=0;
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> update content_node_field set active=1 where active=0;
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2 Changed: 2 Warnings: 0
The CCK Validation module no longer works with Drupal 6, so I migrated to the Validation API module instead. Here are the changes I had to make:
Before (using CCK validation):
$dvd = $node->field_id_of_dvd[0]['nid'];
$checksum = crc32($dvd);
...
if (strval($checksum) !== $node->field_validation_code[0]['value']) {
form_set_error('field_validation_code','this is not the correct validation code for this DVD');
}
After (using Validation API):
$dvd = $form_state['values']['field_id_of_dvd'][0]['nid'];
$checksum = crc32($dvd);
....
if (strval($checksum) !== $value) {
return FALSE;
}
return TRUE;
Here's a short summary of things I had to fix, or had problems with:
This turned out to be even more of a pain in the ass, because the migration process from Views v1.x to Views 2.x is very poor. You'll have to go to the Tools area in the Views GUI, and select to migrate each individual View to the new system. This partially works, i.e. you get the proper View names etc., but you'll have to basically reconfigure all filters, and in some cases, display fields manually. At least that's what I had to do. Here's a short list of things I ended up having to "fix" after the upgrade (this is where having the old site available is a great idea, to see how the old configs were done):
This upgrade is incredibly painful, and I had to try three times before I succeeded. The key tricks here are
Here's a short list of modules that no longer seem to exist for Drupal 6, and what alternatives to use.
Here are some Drupal hacks and modifications that I've done.
I couldn't get the breadcrumb trails (menu) to work with my pages / stories that I structure with node relativity (a Drupal module). I don't know if I'm doing something wrong, but looking at the code, I couldn't see any support for it. So, here it is, a quick and dirty hack to add the breadcrumb trails to your node relativity structures:
--- relativity.module-2.4 2008-09-17 19:44:07.000000000 -0700
+++ relativity.module 2008-09-18 07:49:10.000000000 -0700
@@ -378,6 +378,14 @@
'#title' => t('Global Options'),
);
+ $group['global_options']['relativity_breadcrumb_trails'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Update the breadcrumb trails menu'),
+ '#return_value' => 1,
+ '#default_value' => variable_get('relativity_breadcrumb_trails', 0),
+ '#description' => t('If checked, the ancestor hiearchy of the page is used to create the breadcrumb trail menu.'),
+ );
+
$group['global_options']['relativity_allow_types'] = array(
'#type' => 'select',
'#title' => t('Node types that can be involved in relationships'),
@@ -1067,13 +1075,35 @@
break;
case 'view':
- if ($w = variable_get('relativity_'.$node->type.'_ancestor_weight', 0)) {
+ $do_breadcrumbs = variable_get('relativity_breadcrumb_trails', FALSE);
+ $ancestors_w = variable_get('relativity_'.$node->type.'_ancestor_weight', 0);
+
+ if ($do_breadcrumbs || $ancestors_w) {
$ancestors = relativity_load_ancestors($node);
+
if (is_array($ancestors) && count($ancestors) > 0) {
- $node->content['relativity_ancestors'] = array(
- '#value' => theme('relativity_show_ancestors', $node, $ancestors),
- '#weight' => $w,
- );
+ if ($do_breadcrumbs) {
+ $breadcrumb[] = l(t('Home'), NULL);
+ foreach($ancestors as $ancestor) {
+ if (!is_array($ancestor)) { // Only handle single ancestors here
+ if (array_key_exists("path", $ancestor)) {
+ $breadcrumb[] = l($ancestor->title, $ancestor->path);
+ } else {
+ $breadcrumb[] = l($ancestor->title, 'node/'. $ancestor->nid);
+ }
+ }
+ }
+ if (count($breadcrumb) > 1) {
+ drupal_set_breadcrumb($breadcrumb);
+ }
+ }
+
+ if ($ancestors_w) {
+ $node->content['relativity_ancestors'] = array(
+ '#value' => theme('relativity_show_ancestors', $node, $ancestors),
+ '#weight' => $ancestors_w,
+ );
+ }
}
}
And yes, I did file a "issue" for this, with the Drupal people, http://drupal.org/node/309982 .
This collection of pages is my own personal experience with various 3rd party Drupal modules. I'm not really saying you must have these modules, but I personally find them incredibly useful. I'm not ranking these modules in any particular order, instead I'm trying to organize them by functionality. If you have suggestions for modules that I ought to include here, please let me know, and I'll be happy to add them (after I try 'em of course).
The modules in this section either create new content types, or let you manipulate or create content types.
The CCK module is probably the most important module here, it's a very flexible system that lets you create new content types, or add new custom fields to existing content types. This really is a must have, I actually don't understand why it's not part of core Drupal. There's a number of extra "plugins" for CCK, here are a few that I always add
The Date module is a combination of a complete Date related API, and various extensions for content types, and it integrates nicely with CCK for example.
There's a large number of modules related to images, how to manage and display them, as well as manipulate them. Here's a small collection of must-have's.
I recently had to do an ACL update of a large portion of my content, ACLs which are managed by the Node privacy by-role module. To avoid having to do this manually, and I couldn't find any "GUI" to let me do it, I decided to try it from command line. So, not being a mySQL expert, I still managed to do this from within the mysql client. In my case, I needed to add read permissions to the group of authenticated users, for all content that was viewable by the anonymous user. The SQL code is as follow:
CREATE TEMPORARY TABLE foo AS SELECT nid FROM node_privacy_byrole
WHERE gid=1 AND grant_view=1 AND realm="node_privacy_byrole_role";
UPDATE node_privacy_byrole,foo SET node_privacy_byrole.grant_view=1
WHERE node_privacy_byrole.nid=foo.nid AND node_privacy_byrole.gid=2;