How to Code Display Suite Fields in Drupal

Display Suite Fields

Display Suite module is a useful method of markup development in Drupal. It provides you with the full control on the way of displaying your content via dragging and dropping the fields on the admin panel. This module allows you to create the own fields, which are not “fields” in common understanding. They will appear and be acceptable only on the page of management of displayed content. Using these fields, you can display anything on the content page, moving it in the admin panel with the help of a mouse.

Display Suite Fields in Drupal 7

In Drupal 7, this everything is realized with hook_ds_fields_info().

function hook_ds_fields_info($entity_type) {
 $fields = array();

 // Field definition, in this case, using technical name “title”.
 // They should be unique only within the limits of one entity and among//
 the other DS fields. So, the title here won't overlap title from the entity
 $fields['title'] = array(
   // title:  The title of the field, which will be displayed on the page of management of displayed content.// 
   'title' => t('Title'),
   // field_type: Field type
   // - DS_FIELD_TYPE_THEME      : requests theme() function.
   // - DS_FIELD_TYPE_FUNCTION   : the field result terurns as a function.
   'field_type' => DS_FIELD_TYPE_FUNCTION,
   // ui_limit: Allows you to specify in which variants of display within the entity limits the field is defined for // field will be accessible for use in the following format: $bundle|$view_mode.  You can replace some parts with *, this way
   // specifying what will be accessible in all variants. 
   'ui_limit' => array('article|full', '*|teaser'),
   // file: The path to a file which contents the code is specified here. It's used only
  //for DS_FIELD_TYPE_FUNCTION  type. The path should be full, for example:
   // drupal_get_path('module', 'MYMODULE') . '/inc/file.inc',
   'file' => 'optional_filename',
   // function: The function name which will return the result for
   //  a field. Only for DS_FIELD_TYPE_FUNCTION type.
   'function' => 'theme_ds_title_field',
   // properties: Additional field settings.
   'properties' => array(
     // formatters: optionally for the function and required for
     // DS_FIELD_TYPE_THEME. By the way, for the second one, you should also // // //register the theming function via hook_theme()
//if it’s not present. It will be requested as  theme('function');
     //In this array, the key is a function of theme(), and the value is only a tag for something in// the admin panel. It will be a select where you can choose the output format.      'formatters' => array(
       'node_title_nolink_h1' => t('H1 title'),
       'node_title_link_h1' => t('H1 title, linked to node'),
     ),
     // settings & default: Optionally, used only if you want
     // to add some field settings which will be present in UI.
     'settings' => array(
       'wrapper' => array(
         'type' => 'textfield',
         'description' => t('Eg: h1, h2, p'),
       ),
       'link' => array(
         'type' => 'select',
         'options' => array('yes', 'no'),
       ),
     ),
     'default' => array(
       'wrapper' => 'h2',
       'link' => 0,
     ),
   ),
 );

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

Field Type: DS_FIELD_TYPE_THEME

This field requests the specified function and transfers there all necessary data, field settings, and entity object (if it’s present), to let you get all entity data and a lot of useful information. The function should return the value of this field (row).

Example of Realization in Drupal 7

Let’s imagine that we need to output the number of words from the body field for the article material.

/**
* Implements hook_ds_fields_info().
*/
function mymodule_ds_fields_info($entity_type) {
 $fields = array();

 if ($entity_type == 'node') {
   $fields['word_count'] = array(
     'title' => 'DS: The number of words in the text',
     'field_type' => DS_FIELD_TYPE_FUNCTION,
     //  We need this field only in a full format of displaying article material
     'ui_limit' => array('article|full'),
     // The function name
     'function' => 'mymodule_ds_field_word_count',
   );

   return array($entity_type => $fields);
 }
 return;
}
/**
* The function which will be requested and return the result to the field. 
* If the function returns nothing, false or null, it's 
*considered as an empty field, and it won't be rendered.
*
* @param $field
*  It contains all necessary information for us.
*/
function mymodule_ds_field_word_count($field) {
 // The entity object, which this field was requested for, is contained in
 // $field['entity']. For simplicity and clearness of code we use EMW.
 $entity_wrapper = entity_metadata_wrapper('node', $field['entity']);

 if ($body_value = $entity_wrapper->body->value->value()) {
   // Returning of result.
   return format_string(
     '<strong>The number of worts in the text:</strong> @word_count',
     array(
       '@word_count' => str_word_count(strip_tags($body_value))
     )
   );
 }
}

Field Type: DS_FIELD_TYPE_THEME

This field type requests theme() function, allowing us to transfer values to tpl.php file. It’s useful when we need to enter much wrapping. Also, it helps in case of field ability to change depending on some values. Building HTML right in PHP basing on the conditions through the function will be just unreadable. But the template is pretty helpful here.

Display Suite Fields in Drupal 8

In Drupal 8 hook_ds_fields_info() is replaced with the system of plugins. Display Suite comes with two plugin types DsField and DsFieldTemplate. You can use only DsField for creating fields. Now all fields are specified via one plugin. Drupal 8 has a new feature. Here is the difference: in Drupal 7 the field returned a row with a value, but in Drupal 8 the field must return the render array. So, if you want to return a row, you have to return the render array with markup.

Example of Realization in Drupal 8

Let’s imagine that we need to output the number of words from the body field for the article materials.

namespace DrupalmymodulePluginDsField;

use DrupaldsPluginDsFieldDsFieldBase;
use DrupalComponentRenderFormattableMarkup;
/**
* The field which outputs the number of words in the content.
*
* @DsField(
*   id = "word_count",
*   title = @Translation("DS: Word count"),
*   provider = "mymodule",
*   entity_type = "node",
*   ui_limit = {"article|full"}
* )
*/
class WordCount extends DsFieldBase {
 /**
  * {@inheritdoc}
  *
  * The method which should return the result to the field.
  */
 public function build() {
   // Writing the object of the current entity into a variable for the convenience
   $entity = $this->entity();
   // Check if there is a value in a body field. If the field returnes nothing
   // it takes like empty field and it isn't outputed. 
   if ($body_value = $entity->body->value) {
     return [
       '#type' => 'markup',
       '#markup' => new FormattableMarkup(
         '<strong>?????????? ???? ? ??????:</strong> @word_count',
         [
           '@word_count' => str_word_count(strip_tags($body_value))
         ]
       )
     ];
   }
 }
}

So, this was a quick tip on how to implement your own Display Suite modules in Drupal, no matter what version you use. Hope that it was helpful. If you want to save your time, trust us these works on Drupal, and we’ll do everything you need.

Do you have a question?

Or do you want to talk and share some news? We’ll be glad to communicate with you and clarify all you need. Feel free to contact us anytime, and we’ll reply as soon as possible. Let’s get acquainted and be partners. We’ll be happy to keep in touch with you.

We accept: DOCX, DOC, ODT, PDF

* - required fields