Skip to main content

How to create a custom Display Suite field in Drupal 7

Drupal Display Suite PHP

Display suite (DS) is a powerful tool that allows you to create flexible content on Drupal. While Display Suite is great for layouts there are often times when your fields are not compatible with the DS UI. In this situation you are forced to use a preprocess function, templates, or other methods to display the content. This blog post will take you through how to use the Display Suite API to create a custom field using PHP. I am going to assume that you have knowledge about how Display Suite works and how to create a simple module. The example will be taking an image field and a link field to create a custom field where the image will have a link surrounding it. The first step is telling Display suite about the field using hook_ds_fields_info().

/**
 * Implements hook_ds_fields_info().
 *
 * @return array
 */
function ds_example_ds_fields_info()
{
  $fields['image_link'] = array(
    'title' => t('Image Link'),
    'field_type' => DS_FIELD_TYPE_FUNCTION,
    'function' => 'ds_example_image_link'
  );
  
  return array('node' => $fields);
}

The Display Suite hook takes an associative array of information to let DS know about the custom field. The index value of the associative array can be any string but will need to be unqiue in the return array. In this case its named image_link. The second value is the title that displays under Manage Display tab of your Entity. The field_type is set to DS_FIELD_TYPE_FUNCTION which tells Display Suite that its using a php function to render the field (There are several options here but for this tutorial we are using a function). The last value is function which tells DS the callback function to use in rendering the field. Next lets create the function that will display the field.

/**
 * Implements hook_ds_fields_info().
 *
 * @return array
 */
function ds_example_ds_fields_info()
{
  $fields['image_link'] = array(
    'title' => t('Image Link'),
    'field_type' => DS_FIELD_TYPE_FUNCTION,
    'function' => 'ds_example_image_link'
  );

  return array('node' => $fields);
}

function ds_example_image_link($field)
{
  dpm($field);
}

First dpm the $field variable to ensure that there is a working field. You can use var_dump if needed but should download the devel module if you are following along. From here clear Drupal's cache and go into Manage Display of the content type and enable a display suite layout. This example uses a two column display. Note the field WILL NOT show up if it does not have the content type using a display suite layout.

Display Suite Manage Display

Now write the code to display the field.

/**
 * @file
 * Code for the DS Example feature.
 */

/**
 * Implements hook_ds_fields_info().
 *
 * @return array
 */
function ds_example_ds_fields_info()
{
  $fields['image_link'] = array(
    'title' => t('Image Link'),
    'field_type' => DS_FIELD_TYPE_FUNCTION,
    'function' => 'ds_example_image_link'
  );

  return array('node' => $fields);
}

/**
 * Displays a custom field that is an image wrapped in an anchor
 *
 * @param $field
 * @return string
 */
function ds_example_image_link($field)
{
  $entity = $field['entity'];

  // Get link path
  $path = $entity->field_ds_link[LANGUAGE_NONE][0]['url'];

  // Get the image URI
  $image_uri = $entity->field_ds_image[LANGUAGE_NONE][0]['uri'];

  // Image URL. Note this will render the original image not a image style
  $image_url = '<img src="' . file_create_url($image_uri) . '" />';

  // Lets get the output using drupals rendering.
  $link = array(
    '#theme' => 'link',
    '#text' => $image_url,
    '#path' => $path,
    '#options' => array(
      'attributes' => array('class' => array('ds-image-example')),
      'html' => TRUE,
    ),
  );

  return render($link);
}

First set the entity to its own variable for more readable code. Then grab the path of the link field, the image uri, and then finally use file_create_url to get the image path. Note this is not the best approach to rendering an image due to not being able to render an image style but is being used for this example only. Last we use Drupals built in theme_link function to render the output (The output expects a string but render function is best practices). Refresh the page and the image should appear with an anchor surrounding it. 

Display Suite Final Output

In the example we only return available Display Suite fields for nodes to be able to use. To allow other types of entities to use custom DS fields just return the machine name of the entity in the hook_ds_fields_info. To figure out what the machine name is for the entity look in the module file where it implements hook_entity_info and look for the key value of the array that is returned. For example to use a DS field in field collections the machine name is 'field_collection_item'. Some of the common machine names include: taxonomy_term, user, field_collection_item, profile2

/**
 * Implements hook_ds_fields_info().
 *
 * @return array
 */
function ds_example_ds_fields_info()
{
  $fields['image_link'] = array(
    'title' => t('Image Link'),
    'field_type' => DS_FIELD_TYPE_FUNCTION,
    'function' => 'ds_example_image_link'
  );

  $fields_user['image_link'] = array(
    'title' => t('Image Link for Users'),
    'field_type' => DS_FIELD_TYPE_FUNCTION,
    'function' => 'ds_example_image_link_user_callback'
  );
  
  return array('node' => $fields, 'user' => $fields_user);
}