Exporting and creating field definitions in Drupal 7

I frequently export field definitions so I can programmatically create them in an update.php function. In Drupal 6, the CCK module came bundled with a Content Copy, but (so far) I have found no similar tool in Drupal 7. Here are the tricks I use to do this in a quick an relatively painless way.

Understanding the export functions

Drupal 7 comes with a welcome Field API, which standardizes all the content now stored in nodes, comments, users, and taxonomy terms. The major benefit (in my opinion) is that when you are working with a field—no matter what it is attached to—you can do just about anything you want. But that's beside the point.

The important thing to note is that a field is first it's one thing, and second is attached to a bundle. So, if you've got an image field on your Article content type, you actually have an image field (by itself), and an instance of that field which is attached to the "node" bundle of the type "article". Got it? Good.

If you want export a field definition, you can use the handy field_info_field and field_info_instance functions. Taking our example above, here's how you would call these two functions:

$field_data = field_info_field('field_article_image');
$instance_data = field_info_instance('node', 'field_article_image', 'article');

Understanding the create functions

Now that you have your field and instance definitions, you are ready to create them in your script. Drupal 7 brings two functions which look a lot like their export counterparts, field_create_field and field_create_instance. Just pass in your field definitions, and you're done.

field_create_field($field_data);
field_create_instance($instance_data);

Incorporating this into your development workflow

Now that you understand how it works, let me show you some easy tricks to incorporate this into your development workflow. After you've created your fields using the Field UI, navigate to /devel/php (this requires the must-have Devel module). Then, execute the following, populating the first three variables:

$entity_type = '';
$field_name = 'field_';
$bundle_name = '';

$info_config = field_info_field($field_name);
$info_instance = field_info_instance($entity_type, $field_name, $bundle_name);
unset($info_config['id']);
unset($info_instance['id'], $info_instance['field_id']);
include_once DRUPAL_ROOT . '/includes/utility.inc';
$output = "field_create_field(" . drupal_var_export($info_config) . ");\n";
$output .= "field_create_instance(" . drupal_var_export($info_instance) . ");";
drupal_set_message("<textarea rows=30 style=\"width: 100%;\">" . $output . '</textarea>');

This will do several things. First, it exports your field and instance definitions. Then, it removes the field IDs, so you don't have any ID conflicts when importing. Lastly, it formats the "create" functions for you, and display it inside a textarea which you can copy and paste it into your script.

Making it really, really easy

If you are like me, you'll do this over and over. Instead of bookmarking this article (or trying to memorize it), wouldn't it be nice if you could just punch a keystroke on your computer and have that all populate in the Devel textarea?

Wait, you can! If you use Google Chrome, you can install the Popchrom extension. Create yourself a trigger called "field_export", and put the code above in. Then, when you click Ctrl + Space (or whatever keystroke you've got Popchrom configured to recognize, this little snippet will replace "field_export". Easy, peasy, rice and cheesy.

Final thoughts

I know, I know... we could make a module out of it. Maybe somebody already has. But in the meantime, this gets the job done.