3

Situation I have a custom module that is using hook_field_formatter_info() to add an "fancy" option to the image field in the manage display of a content type. When this option is chosen I want to be able to surround the ENTIRE field in custom divs and markup. I want the solution to be a hook in my custom module and not a template override.

Process A user wants the display of an image field to be the "fancy" option. They check it in the drop down and click save from the content types Manage Display admin page. Now on that content type node there should be custom markup surrounding the entire field even if there are multiple images, the new markup should surround ALL the images and not each individual image.

hook_field_formatter_view hook_field_formatter_view seems to demand it's output be an array and I can't seem to be able to wrap the output in a div.

Template overrides I can't just make a field.tpl.php for the specific field because like I initially mentioned I need to be able to switch themes and the module still work like normal. Unless there is a way to get my module to override any field where said field has hook_field_formatter_info() set specifically.

/**
 * Implements hook_field_formatter_view().
 */
function bootstrap_modal_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();

  foreach ($items as $delta => $item) {
    if ($index === NULL || $index === $delta) {
      $element[$delta] = array(
        '#theme' => 'bootstrap_modal_image_formatter',
        '#item' => $item,
        '#entity_type' => $entity_type,
        '#entity' => $entity,
        '#node' => $entity, // Left for legacy support.
        '#field' => $field,
        '#display_settings' => $display['settings'],
        '#delta' => $delta,
      );
    }
  }


  // $element = '<div id="CUSTOMDIVSTUFF">' . $element . '</div>';

  return $element;
}

And here is the #theme function:

function theme_bootstrap_modal_image_formatter($variables) {

  $item = $variables['item'];
  $entity_type = $variables['entity_type'];
  $entity = $variables['entity'];
  $field = $variables['field'];
  $settings = $variables['display_settings'];

  $image = array(
    'path' => $item['uri'],
    'alt' => isset($item['alt']) ? $item['alt'] : '',
    'title' => isset($item['title']) ? $item['title'] : '',
    'style_name' => $settings['bootstrap_modal_node_style'],
  );

  if (isset($item['width']) && isset($item['height'])) {
    $image['width'] = $item['width'];
    $image['height'] = $item['height'];
  }

  if (isset($item['attributes'])) {
    $image['attributes'] = $item['attributes'];
  }

  // Allow image attributes to be overridden.
  if (isset($variables['item']['override']['attributes'])) {
    foreach (array('width', 'height', 'alt', 'title') as $key) {
      if (isset($variables['item']['override']['attributes'][$key])) {
        $image[$key] = $variables['item']['override']['attributes'][$key];
        unset($variables['item']['override']['attributes'][$key]);
      }
    }
    if (isset($image['attributes'])) {
      $image['attributes'] = $variables['item']['override']['attributes'] + $image['attributes'];
    }
    else {
      $image['attributes'] = $variables['item']['override']['attributes'];
    }
  }

  $entity_title = entity_label($entity_type, $entity);

  if ($style_name = $settings['bootstrap_modal_image_style']) {
    $path = image_style_url($style_name, $image['path']);
  }
  else {
    $path = file_create_url($image['path']);
  }

  $caption = 'some value';
  $gallery_id = 'some value';

  return theme('bootstrap_modal_imagefield', array('image' => $image, 'path' => $path, 'title' => $caption, 'gid' => $gallery_id));
}

Been working on this for days, I'm drowning here.

2

Might be misunderstanding but it sounds like you just want a #prefix and #suffix on the base render element:

function bootstrap_modal_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array(
    '#prefix' => '<div class="wrapper">',
    '#suffix' => '</div>',
  );

  ...
  • This is totally the solution, the thing I'm wondering is why it wasn't on the hook page (api.drupal.org/api/drupal/modules!field!field.api.php/function/…) How would I have found this? I certainly have seen #prefix and #suffix before in other areas and other modules but there wasn't a clear connection between this hook and these array values. – josephleon Nov 19 '14 at 11:28
  • The important thing to know/remember is that you're dealing with a render array - that's a global concept in Drupal, and certain properties (those prefixed with #) make sense to, and are aplicable to, all render arrays. #prefix and #suffix are two such properties, they wouldn't be mentioned in the context of a specific render array, because they're implicitly available to all – Clive Nov 19 '14 at 11:41
  • Is there a place which lists all values which are accepted by render arrays? I tried to upvote you but dont have enough rep yet. – josephleon Nov 21 '14 at 18:28
  • Not as such @josephleon, the nature of render arrays means that properties (the array keys with # in front of them) are arbitrary. There's more info that might help to explain here and here. Common ones are #prefix, #suffix, #theme, and the ones defined by the form API. Just to confuse things, those docs include #prefix and #suffix - not every... – Clive Nov 21 '14 at 18:55
  • ...form API property is valid outside the context of a form render array. It's a bit of a minefield to be honest – Clive Nov 21 '14 at 18:56
1

I think form alter would be a better choice:

function MODULE_form_alter(&$form, &$form_state, $form_id) {
  switch ($form_id) {
    case 'FORM_ID':
      $form['fieldA'] = array(
            '#prefix' => '<div class="wrapper">',
            '#suffix' => '</div>',
      );
      break;
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.