You are here

field_formatter_filter.module in Field Formatter Filter 7

Same filename and directory in other branches
  1. 8 field_formatter_filter.module
  2. 2.0.x field_formatter_filter.module

Allows different text format filters to be applied as part of the field formatter settings for text fields.

File

field_formatter_filter.module
View source
<?php

/**
 * @file
 * Allows different text format filters to be applied as part of the field
 * formatter settings for text fields.
 */

/**
 * Returns true if the field type is filterable.
 *
 * Internal utility.
 *
 * @param string $type
 *   Field type.
 *
 * @return bool
 *   Is this a filterable field type.
 */
function field_formatter_filter_target_field_type($type) {

  // Only alter longtext sorta fields.
  return in_array($type, array(
    'text',
    'text_long',
    'text_with_summary',
  ));
}

/**
 * Add my default setting to each formatter that applies to longtext fields.
 *
 * Implements hook_field_formatter_info_alter().
 */
function field_formatter_filter_field_formatter_info_alter(&$info) {

  // Add myself to the long text formatters.
  $targets = array(
    'text_default',
    'text_plain',
    'text_trimmed',
    'text_summary_or_trimmed',
  );
  foreach ($targets as $target_formatter) {
    if (is_array($info[$target_formatter]['settings'])) {
      $info[$target_formatter]['settings'] += array(
        'field_formatter_filter' => NULL,
      );
    }
    else {

      // Should not happen.
      // Not sure how this can come about, but I encountered it when configuring
      // a display_suite dynamic field. Just not initialized yet I guess.
    }
  }

  // Alternatively, I could search every field that affects
  // array('text', 'text_long', 'text_with_summary')
  // type fields. Similar result.
}

/**
 * Displays the formatter setting on the manage field display overview.
 *
 * Implements hook_field_formatter_settings_summary_alter().
 */
function field_formatter_filter_field_formatter_settings_summary_alter(&$summary, $context) {
  if (!field_formatter_filter_target_field_type(@$context['field']['type'])) {
    return;
  }
  $display = $context['instance']['display'][$context['view_mode']];
  $settings = $display['settings'];
  if (!empty($summary)) {
    $summary .= '<br />';
  }
  if (!empty($settings['field_formatter_filter'])) {
    $filter_format = filter_format_load($settings['field_formatter_filter']);
    $summary .= t('Text filter: @filter_format', array(
      '@filter_format' => $filter_format->name,
    ));
  }
  else {
    $summary .= "<!-- Need this or settings do not show up on plain -->";
  }
}

/**
 * Adds our option to the field formatter settings UI.
 *
 * Implements hook_field_formatter_settings_form_alter().
 */
function field_formatter_filter_field_formatter_settings_form_alter(&$settings_form, $context) {
  if (!field_formatter_filter_target_field_type($context['field']['type'])) {
    return;
  }
  $display = $context['instance']['display'][$context['view_mode']];
  $settings = $display['settings'];
  $filter_format_options[''] = '<none>';
  foreach (filter_formats() as $format) {
    $filter_format_options[$format->format] = $format->name;
  }
  if (!empty($settings['field_formatter_filter'])) {
    $description = theme('filter_tips', array(
      'tips' => _filter_tips($settings['field_formatter_filter'], FALSE),
    ));
  }
  $settings_form['field_formatter_filter'] = array(
    '#type' => 'select',
    '#title' => t('Additional Text Filter'),
    '#options' => $filter_format_options,
    '#default_value' => $settings['field_formatter_filter'],
    '#description' => !empty($description) ? filter_xss($description) : '',
  );
}

/**
 * Runs the text through the given filter.
 *
 * We assume that the normal filter has already run here
 * - the items #markup is already prepared.
 *
 * hook_preprocess field is right down close to the theme phase.
 * There may be an earlier point to catch this.
 * #markup was set when it hit text_field_formatter_view
 *
 * Implements hook_preprocess_field().
 */
function field_formatter_filter_preprocess_field(&$variables, $hook) {
  $entity_type = $variables['element']['#entity_type'];
  $field_name = $variables['element']['#field_name'];
  $bundle = $variables['element']['#bundle'];
  $view_mode = $variables['element']['#view_mode'];
  $formatter_info = field_formatter_settings_get_instance_display_settings($entity_type, $field_name, $bundle, $view_mode);
  if (!empty($formatter_info['field_formatter_filter'])) {
    $format_id = $formatter_info['field_formatter_filter'];
    $language = $variables['element']['#language'];
    foreach ($variables['items'] as $delta => $item) {
      $variables['items'][$delta]['#markup'] = check_markup($item['#markup'], $format_id, $language);
    }
  }
}

/**
 * Advertises a new type of text display : 'Remainder after trimming'.
 *
 * Implements hook_field_formatter_info().
 */
function field_formatter_filter_field_formatter_info() {
  return array(
    // The 'remainder after trimming' field formatter for text_with_summary
    // is the complement of 'summary or trimmed'.
    // It chops off the teaser and shows what is left.
    'text_remainder_after_trimming' => array(
      'label' => t('Remainder after trimming'),
      'field types' => array(
        'text_with_summary',
      ),
      'settings' => array(
        'trim_length' => 600,
      ),
    ),
  );
}

/**
 * Implements hook_field_formatter_settings_form().
 */
function field_formatter_filter_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  $element = array();
  if ($display['type'] == 'text_remainder_after_trimming') {
    $element['trim_length'] = array(
      '#title' => t('Trim length'),
      '#type' => 'textfield',
      '#size' => 10,
      '#default_value' => $settings['trim_length'],
      '#element_validate' => array(
        'element_validate_integer_positive',
      ),
      '#required' => TRUE,
    );
  }
  return $element;
}

/**
 * Produces the result of stripping test to 'text_remainder_after_trimming'.
 *
 * Implements hook_field_formatter_view().
 */
function field_formatter_filter_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  switch ($display['type']) {
    case 'text_remainder_after_trimming':

      // Produce the inverse of summary_or_trimmed.
      foreach ($items as $delta => $item) {
        if (!empty($item['summary'])) {

          // This means a specific summary was defined.
          // So the value is defined separate.
          $output = _text_sanitize($instance, $langcode, $item, 'value');
        }
        else {

          // Calculate the remainder.
          $output = _text_sanitize($instance, $langcode, $item, 'value');

          // First grab the calculated summary, but take care to avoid
          // the htmlcorrector getting involved.
          // So, do not pass in a text format.
          $format = NULL;
          $summary = text_summary($output, $format, $display['settings']['trim_length']);
          $output = str_replace($summary, '', $output);

          // Now may need to run htmlcorrector.
          $format = $instance['settings']['text_processing'] ? $item['format'] : NULL;
          $filters = filter_list_format($format);

          // If the htmlcorrector filter is present, apply it to the generated
          // summary.
          if (isset($filters['filter_htmlcorrector'])) {
            $summary = _filter_htmlcorrector($summary);
          }
        }
        $element[$delta] = array(
          '#markup' => $output,
        );
      }
      break;
  }
  return $element;
}

Functions

Namesort descending Description
field_formatter_filter_field_formatter_info Advertises a new type of text display : 'Remainder after trimming'.
field_formatter_filter_field_formatter_info_alter Add my default setting to each formatter that applies to longtext fields.
field_formatter_filter_field_formatter_settings_form Implements hook_field_formatter_settings_form().
field_formatter_filter_field_formatter_settings_form_alter Adds our option to the field formatter settings UI.
field_formatter_filter_field_formatter_settings_summary_alter Displays the formatter setting on the manage field display overview.
field_formatter_filter_field_formatter_view Produces the result of stripping test to 'text_remainder_after_trimming'.
field_formatter_filter_preprocess_field Runs the text through the given filter.
field_formatter_filter_target_field_type Returns true if the field type is filterable.