Mean in green
I'm Kevin. I live in Salem, Mass with my wife and little boy and I build software.

Migrating the Drupal way. Part I: creating a node.

Friday Nov 14, 2008

My position with Acquia will find me helping out with a lot of migrations and upgrades. I'm going to embark on a multiple-part blog to discuss some of the common techniques that I use when moving clients to Drupal.

Migrating to Drupal can seem intimidating if you already maintain a database-driven website. However, populating a Drupal site with your current content might be easier than you think. Whether you are migrating from a popular CMS or a fully custom application, you can easily use Drupal modules to mimic your current data structures and migrate your data using a simple custom PHP script. I should note that while there are several different methods to accomplish this task, this happens to be my favorite.

When interacting with Drupal, it's a good idea to do things the Drupal way. Fortunately, Drupal core allows you to bootstrap Drupal and use all of its API functionality outside of a normal Drupal instance. For yours truly, learning about this has been a godsend because it provides a fast, simple way to migrate data.

Creating a basic node

When writing an import script, you will need to bootstrap Drupal to use the API functions. Using drupal_bootstrap($phase), you can load Drupal up to a certain loading phase by designating a $phase argument. The value of $phase allows you to specifically load the site configuration, database layer, modules and other requisite functionality. For our purposes, we will use drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL) to make sure that we have access to the whole API.

Note: Make sure that you create this script in the root of your Drupal installation.


// Bootstrap Drupal require 'includes/'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); ?>

For a simple example, we will create a basic node object and save it in our Drupal database using node_save().


// Construct the new node object. $node = new stdClass();

// Your script will probably pull this information from a database. $node->title = "My imported node"; $node->body = "The body of my imported node.\n\nAdditional Information"; $node->type = 'story'; // Your specified content type $node->created = time(); $node->changed = $node->created; $node->status = 1; $node->promote = 1; $node->sticky = 0; $node->format = 1; // Filtered HTML $node->uid = 1; // UID of content owner $node->language = 'en'; // If known, the taxonomy TID values can be added as an array. $node->taxonomy = array(2,3,1,);

node_save($node); ?>

Creating more complex nodes

The script above will create a new node with a title and body that is published and promoted to the homepage. However, the process becomes more slightly more complicated if you have more data than simple title and body fields. The CCK module is a popular method to extend your nodes by adding any number of custom fields. When Drupal displays your content, CCK adds your custom fields to the node object using hook_nodeapi(). Luckily, you can replicate this by adding your own fields in the import script. So, how can you find out the structure of these fields? One really easy method is to use the Devel module.

CCK Custom FieldsThe Devel module can be used to show how Drupal sees your node object

Using the Devel module

The Devel module is a great way to see, among other things, the structure of the node object which is invaluable in this case. After installing the module and viewing a node you will see new tabs: Dev load and Dev render. Click the Dev load tab, then click the "... (Object) stdClass" header to expand the node object definition. Here you will find some familiar data like nid, type, etc. Near the bottom, you will see some other definitions that begin with "field_". These should resemble the CCK fields that you created for your node type.

Depending on your CCK definitions, the assignments in your import script might look like one of the following:

Devel Load Module TabHere you can see some examples of how CCK has added fields to the node object


$node->field_text_field[0]['value'] = "value 1"; $node->field_text_field[1]['value'] = "2nd value"; $node->field_nodereference[0]['nid'] = 58; ?>

Add these assignments to your import script and you will start to see the power of the Drupal API. Let's say you are migrating from another CMS with a number of related fields, categories, images, etc. You could expand this script to iterate through your old database and map all of the related elements to a corresponding node object. Execute your script, and all of your old data will now become Drupal data! The best part about using the API is that it takes care of all of everything from search indexing to path aliases and all of the other little things we might overlook.

Migrating to Drupal can seem like a daunting task, but when doing things the Drupal way it's quite straight forward. Whether you are planning a migration of 100 nodes or 100,000 nodes, proper scripting can make it seem like a breeze!