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 :)