You are here

textformatter.module in Text list formatter 8.2

Same filename and directory in other branches
  1. 6 textformatter.module
  2. 7 textformatter.module

Provide a field formatter to render values as HTML or comma-separated lists.

File

textformatter.module
View source
<?php

/**
 * @file
 * Provide a field formatter to render values as HTML or comma-separated lists.
 */
use Drupal\textformatter\Plugin\field\formatter\ListFormatter;
use Drupal\Core\Template\Attribute;

/**
 * Implements hook_help().
 */
function textformatter_help($path, $arg) {
  switch ($path) {
    case 'admin/help#textformatter':
      $output = '<p>' . t("The text formatter module provides a new display formatter that can\n        be used on any text, number, list, or taxonomy fields.") . '</p>';
      $output .= '<p>' . t("Go to 'Manage display' for your entity field display settings and\n        select 'List' as the formatter. Various options will then be available to either format\n        your field values as an html list or comma separated list.") . '</p>';
      $output .= '<p>' . t("This would be mostly implemented with multi value fields.\n        E.g. A text field could be created with unlimited values. Each value will then be added to\n        the same html list. Taxonomy terms will work with comma separated auto complete lists too,\n        to give the same result. The only exceptions are textarea field, lists can be created based\n        on each line of the input.") . '</p>';
      return $output;
  }
}

/**
 * Implements hook_field_formatter_info_alter().
 */
function textformatter_field_formatter_info_alter(&$info) {
  $textformatter_info = ListFormatter::prepareFieldListInfo();
  $info['list_formatter']['field_types'] = $textformatter_info['fields'];
  $info['list_formatter']['settings']['contrib'] = $textformatter_info['settings'];
}

/**
 * Implements hook_theme().
 */
function textformatter_theme($existing, $type, $theme, $path) {
  return array(
    'textformatter_comma' => array(
      'variables' => array(
        'items' => NULL,
        'formatter' => NULL,
        'attributes' => NULL,
      ),
    ),
  );
}

/**
 * Implements hook_textformatter_field_info().
 */
function textformatter_textformatter_field_info() {
  $info = array();
  $info['text'] = array(
    'fields' => array(
      'text',
      'text_long',
      'text_with_summary',
    ),
    'callback' => 'textformatter_text_field_create_list',
  );
  $info['number'] = array(
    'fields' => array(
      'number_integer',
      'number_decimal',
      'number_float',
    ),
  );
  $info['list'] = array(
    'fields' => array(
      'list_float',
      'list_integer',
      'list_text',
    ),
    'callback' => 'textformatter_list_field_create_list',
  );
  $info['taxonomy'] = array(
    'fields' => array(
      'taxonomy_term_reference',
    ),
    'callback' => 'textformatter_taxonomy_field_create_list',
  );
  return $info;
}

/**
 * Create list for text fields.
 */
function textformatter_text_field_create_list($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $settings = $display['settings'];
  $list_items = array();
  if ($field['type'] == 'text_long') {
    foreach ($items as $delta => $item) {

      // Explode on new line char, trim whitespace (if any), then array filter (So any empty lines will actually be removed).
      $long_text_items = array_filter(array_map('trim', explode("\n", $item['value'])));
      foreach ($long_text_items as $long_text_item) {

        // @see _text_sanitize(), text.module
        $list_items[] = $instance['settings']['text_processing'] ? check_markup($long_text_item, $item['format'], $langcode) : field_filter_xss($long_text_item);
      }
    }
  }
  else {
    foreach ($items as $delta => $item) {
      $list_items[] = $instance['settings']['text_processing'] ? check_markup($item['value'], $item['format'], $langcode) : field_filter_xss($item['value']);
    }
  }
  return $list_items;
}

/**
 * Create list for list fields.
 */
function textformatter_list_field_create_list($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $settings = $display['settings'];
  $list_items = array();

  // Get allowed values for the field.
  $allowed_values = list_allowed_values($field);
  foreach ($items as $delta => $item) {
    if (isset($allowed_values[$item['value']])) {
      $list_items[$delta] = field_filter_xss($allowed_values[$item['value']]);
    }
  }
  return $list_items;
}

/**
 * Create list for taxonomy reference fields.
 */
function textformatter_taxonomy_field_create_list($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $settings = $display['settings'];
  $list_items = $tids = array();

  // Get an array of tids only.
  foreach ($items as $item) {
    $tids[] = $item['tid'];
  }
  $terms = taxonomy_term_load_multiple($tids);
  foreach ($items as $delta => $item) {

    // Check the term for this item has actually been loaded.
    // @see http://drupal.org/node/1281114
    if (empty($terms[$item['tid']])) {
      continue;
    }

    // Use the item name if autocreating, as there won't be a term object yet.
    $term_name = $item['tid'] === 'autocreate' ? $item['name'] : $terms[$item['tid']]->name;

    // Check if we should display as term links or not.
    if ($settings['term_plain'] || $item['tid'] === 'autocreate') {
      $list_items[$delta] = check_plain($term_name);
    }
    else {
      $uri = $terms[$item['tid']]
        ->uri();
      $list_items[$delta] = l($term_name, $uri['path']);
    }
  }
  return $list_items;
}

/**
 * Validate that a space-separated list of values are lowercase and appropriate
 * for use as HTML classes.
 *
 * @see textformatter_field_formatter_settings_form()
 */
function _textformatter_validate_class($element, &$form_state) {
  $value = drupal_array_get_nested_value($form_state['values'], $element['#parents']);
  $classes = explode(' ', $value);
  foreach ($classes as $class) {
    if ($class != drupal_html_class($class)) {
      form_error($element, t('List classes contain illegal characters; classes should be lowercase and may contain letters, numbers, and dashes.'));
      return;
    }
  }
}

/**
 * Helper to return the value key for a field instance.
 *
 * @param $field array
 *  The whole array of field instance info provided by the field api.
 *
 * @return string
 *  The value key for the field.
 */
function _textformatter_get_field_value_key(array $field) {
  return array_key_exists('columns', $field) && is_array($field['columns']) ? key($field['columns']) : 'value';
}

/**
 * Theme function to render comma separated lists.
 */
function theme_textformatter_comma($variables) {
  $items = $variables['items'];
  $formatter = $variables['formatter'];
  $attributes = new Attribute($variables['attributes']);

  // Optionally prefix the last item with 'and'.
  $last = '';
  if ($formatter
    ->getSetting('comma_and') && count($items) > 1 && !$formatter
    ->getSetting('comma_override')) {
    $last = ' ' . t('and') . ' ' . array_pop($items);
  }

  // Default comma separator.
  $separator = ', ';

  //Override if we need to.
  if ($formatter
    ->getSetting('comma_override')) {
    $sep = check_plain($formatter
      ->getSetting('separator_custom'));
    $tag = $settings['separator_custom_tag'];
    if ($tag) {
      $class = $formatter
        ->getSetting('separator_custom_class');
      $separator = "<{$tag} class=\"{$class}\">{$sep}</{$tag}>";
    }
  }

  // Generate a comma-separated list.
  $output = implode($separator, $items) . $last;

  // Optionally follow the list with a '.'.
  if ($formatter
    ->getSetting('comma_full_stop')) {
    $output .= '<span class="textformatter-fullstop">.</span>';
  }

  // Optionally wrap the list in an HTML tag.
  $tag = $formatter
    ->getSetting('comma_tag');
  if ($tag) {
    $output = "<{$tag}{$attributes}>{$output}</{$tag}>";
  }
  return $output;
}

Functions

Namesort descending Description
textformatter_field_formatter_info_alter Implements hook_field_formatter_info_alter().
textformatter_help Implements hook_help().
textformatter_list_field_create_list Create list for list fields.
textformatter_taxonomy_field_create_list Create list for taxonomy reference fields.
textformatter_textformatter_field_info Implements hook_textformatter_field_info().
textformatter_text_field_create_list Create list for text fields.
textformatter_theme Implements hook_theme().
theme_textformatter_comma Theme function to render comma separated lists.
_textformatter_get_field_value_key Helper to return the value key for a field instance.
_textformatter_validate_class Validate that a space-separated list of values are lowercase and appropriate for use as HTML classes.