Jun 04, 2019 in Drupal 8

Custom formatters are great to get precise control over your field output. But I ran into something difficult when trying to output the description of a file field. It seemd that the description is stored on the filefield, and not on the file entity. This code shows you how to do it. 

Create a file called CustomFileFormatter.php inside a custom module (map src/Plugin/Field/FieldFormatter) and add the following code: 

<?php
// snippet: https://stefvanlooveren.me/node/72
namespace Drupal\custom_formatters\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\file\Plugin\Field\FieldFormatter\FileFormatterBase;

/**
 * Plugin implementation of a custom formatter.
 *
 * @FieldFormatter(
 *   id = "file_description_viewer",
 *   label = @Translation("File custom: show file and description"),
 *   field_types = {
 *     "file"
 *   }
 * )
 */
class CustomFileFormatter extends FileFormatterBase {

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {

    $elements = array();

    foreach ($this->getEntitiesToView($items, $langcode) as $delta => $file) {
      $item = $file->_referringItem;
      $uri = $file->getFileUri();
      $file_path = file_create_url($uri);
      $filename = $file->getFileName();
      $description = isset($item->description) ? '<small>'.$item->description.'</small>' : null;
      $elements[$delta]['#markup'] = '';
      $elements[$delta]['#markup'] .= '<div class="custom-file-viewer">
                                          <a class="download-link" href="' .$file_path. '">' . $filename . '</a>
                                          '.$description.'
                                         </div>';

      $elements[$delta]['#allowed_tags'] = ['div', 'a', 'small'];
    }
    return $elements;
  }

}