How To Export Fields & Display Suite View Modes

One thing that's often forgotten when I see tutorials about exporting view modes the variable that ties it all together, the field bundle settings for a content type.

This has cost me hours to figure out, after which I forgot it and it cost me hours again, frustratingly trying to figure out why, with seemingly everything exported well, the content types would just not have the view modes that I configured in Drupal's UI.

I don't like to work with Features. Features are fine until they're not. Features generate conflicts and remain in an overridden state after a while. I don't like it. Features are a black box, but the black box does not "just work". Raise your hand if you've heard this before when working on a Drupal project in a team:

"Hey, I reverted the features but it remains overridden."
-- "Ahh yes, I don't know why. It's fine though."

So often everybody assumes it's fine but basically nobody has a clue anymore about what's going on with that feature in a website.

That's why with the last project I did I said, no features. We do everything in code. Which, admittedly, is a bit crazy too. You burn more time, and thus money, on the project putting all the field bases, field instances, Display Suite field info and Display Suite view layouts into code.

Panels and views on the other hand are easier when working in code. Adjust anything in a panel or view, export it. Copy and paste the whole thing into the panel or view's code file and you're good to go. Way faster than working with features.

Exporting fields
To export fields you can use Features, install the module and create a feature containing your content types' field bases and field instances. Of course you need to create your content type first which goes like this:

$my_content_type = array(
  'type' => 'my_content_type',
  'name' => $t('My content type'),
  'base' => 'node_content',
  'title_label' => $t('Title'),
  'description' => $t('My content type for my website.'),
  'custom' => TRUE,
);

$content_type = node_type_set_defaults($my_content_type);
node_add_body_field($content_type, $t('Body'));
node_type_save($content_type);

Exporting field bases
You take the field_base.inc file and copy paste each field base piece of code into a field_create_field() method in your own module's install file. I created a MY_MODULE.field_info.inc file because field bases are shared across content types. You can re-use them.

Exporting field instances
For the field instances I created a MY_MODULE.MY_CONTENT_TYPE.inc for each content type and, at first, copy/pasted each field instance bit of code into a field_create_instance() method in content type's file. Field instances are not shared and it's nice to keep them separate. Beware that when you modify the body field in a content type you don't field_create_instance but field_update_instance for that.

Because you don't do everything right the first time around and you'll be adding or shuffling fields throughout the development of the project I got tired of copy/pasting each section, seeing which field I've already done, afraid of having missed one. The output of MY_FEATURE.field_instance.inc is almost exactly what has to be copy pasted into MY_MODULE.MY_CONTENT_TYPE.inc so I've created a little sed command file that roughly whips *.field_instance.inc into shape.

If you put these lines in a separate file and then call: sed -f command_file MY_FEATURE.field_instance.inc you can almost copy and paste the whole output into your own file.

s/\$field_instances\['.*'\] = /field_create_instance(/
s/\/\/.*//
s/^\([ ]*\));/\1));/
s/^[ ]*return.*//

Exporting Display Suite view modules
To export view modes I use Bulk Export, which comes with Ctools. Just enable the module and you'll get a new item in the Structure menu of your Drupal website. Select which Display Suite view modes you'd like to export and it'll present you with code that you can copy paste into your code.

However, the field bundle settings, a variable that gets saved whenever you "add" a view mode to a content type does not get exported when exporting Display Suite view modes through Bulk Export. Nor does it get exported through Features, not unless you have an extra "Strongarm" module installed at least.

In Kristof De Jaeger (@swentel)'s YouTube video about exporting Display Suite view modes he also makes no mention of this. All he does there after having configured and exported his view modes is truncating the various ds_* tables in Drupal's database, but he forgets about the field_bundle_settings_* It "works" in his demo because he doesn't start from a clean database. But if you'd take the code and deploy it on a new website, that field_bundle_settings_* variable would be missing and the view mode would not be connected to the content type.

You can solve that nasty time-wasting problem by putting this piece of code into your install file for each view mode. In this case it's for the full view mode.

// Update view mode full mode for some content types
$bundles_full_view = array('my_content_type', my_content_type_2);
foreach ($bundles_full_view as $bundle) {
  $settings = variable_get('field_bundle_settings_node__' . $bundle, array());
  $settings['view_modes']['full']['custom_settings'] = TRUE;
  variable_set('field_bundle_settings_node__' . $bundle, $settings);
}

This adds a field_bundle_settings_node_* variable for each content type you want to use the "full view" Display Suite view mode for.

Install a module with _that_ variable defined in it on a clean database and everything _will_ work out of the box.

To recap, when you want to

  • export content types
  • export their fields and the fields' label settings
  • export the view modes used by the content type
  • export the Display Suite field settings

you have to

  • Add the content type through node_type_save()
  • Add each field base with field_create_field()
  • Add each field instance on the content type with field_create_instance(). This also contains the label settings (hidden, above, inline) and in which view mode they appear.
  • Add the field_bundle_settings variable with a variable_set() to tell Drupal which view modes a content type uses.
  • Export Display Suite settings and add the layouts and field info hooks to your code to tell Drupal about the layout in each view mode and the field attributes and extras that got added, if any.