Drupal - Hook into other module's field formatter?

The question mentions that hook_field_formatter_view() is only called on the originating module, but you can take ownership of the field formatter via hook_field_formatter_info_alter().

You should be able to set the module key of the formatter to MYMODULE like:

function MYMODULE_field_formatter_info_alter(&$info) {
  $info['some_field_formatter']['module'] = 'MYMODULE';
}

Then you can implement MYMODULE_field_formatter_view(), optionally feeding through the existing module which handled it to get an element to alter.

function MYMODULE_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  // Your custom logic
  $element = OTHER_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display);
  // Any alterations
}

Ok so I realised why my changes to #view_mode in either hook_preprocess_node and hook_preprocess_fields weren't working. (Thanks to Clive for pointing out that I had totally missed the presence of #view_mode in hook_preprocess_node).

My problem stemmed from the fact that #view_mode had already been processed and converted to the correct #image_style property — something which I had neglected to search for.

Even so, changing this value seems too heavily dependent on which hook you modified it in. I finally got some code working though, that actually changes the rendered image:

function HOOK_preprocess_field( &$vars ){
  $element     = &$vars['element'];
  $entity_type = !empty($element['#entity_type']) ? $element['#entity_type'] : 'unknown';
  $bundle      = !empty($element['#bundle'])      ? $element['#bundle']      : 'unknown';
  $view_mode   = !empty($element['#view_mode'])   ? $element['#view_mode']   : 'unknown';
  $field_name  = !empty($element['#field_name'])  ? $element['#field_name']  : 'unknown';
  switch ( "$entity_type:$view_mode:$bundle/$field_name" ) {
    case 'node:full:mlandingpage/field_lead_image':
      if ( !empty($vars['items']) && 
           ($subelement = &$vars['items'][0]) ) {
        if ( !empty($subelement['field_image']) && 
             ($subfield = &$subelement['field_image'][0]) ) {
          /// this needs to be set to the image_style value, not the view_mode value.
          $subfield['#image_style'] = 'grid-normal-4-cols';
        }
      }
    break;
  }
}

The above still doesn't feel very eloquent, but at least it works. I'll take Clive's word on the fact that such an _alter method doesn't exist for field formatters — it's a shame, formatters are an extremely powerful feature of D7, it would be nice to have more augmenting ability.

Anyway, if any future people have any better ideas, answer away :)

Tags:

Entities