1

I'm altering the way images are rendered in the node preprocess function, and it is working exactly as expected for images in "Image" fields:

$field_view = $fields['field_image']->view(['label' => 'hidden']);
$field_view['#view_mode'] = 'full';

This results in the regular image array, so when I add it to my twig template, it gets rendered as an image tag.

However, we'd like to start using Media fields instead, and I can't figure out how to get the render array to come back with an image instead of just a text link. If I use the same thing for a media field, I just get a link with the image title as the text of the link:

$field_view = $fields['field_media_image']->view([
  'label' => 'hidden',
]);

This is what the 'file' image render array looks like; it renders as an image, which is what I want to get for the media image field:

#theme => "field"
#title => "Image"
#label_display => "hidden"
#view_mode => "full"
#language => "und"
#field_name => "field_image"
#field_type => "image"
#field_translatable => true
#entity_type => "node"
#bundle => "page"
#object => Drupal\node\Entity\Node (29)
#items => Drupal\file\Plugin\Field\FieldType\FileFieldItemList (9)
#formatter => "image"
#is_multiple => false
#third_party_settings => array (0)
0 => array (6)
#cache => array (3)
#weight => 0

However, when I just use the same view() function on the media image field, I get this, which doesn't render as an image:

#theme => "field"
#title => "Media Image"
#label_display => "hidden"
#view_mode => "_custom"
#language => "und"
#field_name => "field_media_image"
#field_type => "entity_reference"
#field_translatable => false
#entity_type => "node"
#bundle => "page"
#object => Drupal\node\Entity\Node (29)
#items => Drupal\Core\Field\EntityReferenceFieldItemList (9)
#formatter => "entity_reference_label"
#is_multiple => false
#third_party_settings => array (0)
0 => array (5)
#cache => array (3)
#weight => 0

I would guess that the reason this renders as a textual link is because of #formatter => "entity_reference_label" but whenI change this value, I continue to get the same output.

2

2 Answers 2

1

Try this:

if ($node->hasField('field_name') && $node->get('field_name')->entity) {

  // Set media entity.
  $mediaEntity = $node->get('field_name')->entity;

  // Get media image field.
  $mediaImage = $mediaEntity->get('field_media_image');

  // Get translated media image field.
  if ($mediaEntity->hasTranslation($langcode)) {
    $mediaImage = $mediaEntity->getTranslation($langcode)->get('field_media_image');
  }

  // Get media image entity.
  $mediaImageEntity = $mediaImage->entity;

  // Get image mime type.
  $mediaImageMimeType = $mediaImageEntity->getMimeType();

  // Get image file uri.
  $mediaImageEntityUri = $mediaImageEntity->getFileUri();

  // Set image url.
  $imageUrl = \Drupal::service('file_url_generator')->generateString($mediaImageEntityUri);

  // Set image style url.
  if ($mediaImageMimeType !== "image/svg+xml") {
    $imageUrl = \Drupal::entityTypeManager()->getStorage('image_style')->load('image_style_name')->buildUrl($mediaImageEntityUri);
  }

  $variables['imageUrl'] = $imageUrl;
}
1
  • Thanks for looking at this; I'm not trying to just get the URL, although I suppose that would allow me to build my own image output. With the regular image field, I'm able to just use the $field->view() to generate a render array, and I'd like to use the same method (or equivalent) to render the media image field.
    – safetypin
    Commented Oct 2, 2023 at 13:43
1

Don't switch the field formatter, switch the entire entity view mode. I've done something similar with Paragraphs and media view modes, the following code is copy&paste from my project. It should be easy to adjust for nodes.

I just replaced the #view_mode key in the render array, but you have to do it for every single ER field value

function theme_preprocess_paragraph(array &$variables) {
  $paragraph = $variables['paragraph'];
  if ($paragraph->hasField('field_image_viewmode')) {
    $imageViewMode = $paragraph->field_image_viewmode->value;
    if (!$paragraph->field_gallery->isEmpty()) {
      $mediaEntities = $paragraph->field_gallery->referencedEntities();
      foreach ($mediaEntities as $idx => $mediaEntity) {
        // this is the key line
        $variables['content']['field_gallery'][$idx]['#view_mode'] = $imageViewMode;
        // this operation is not cache-safe
        unset($variables['content']['field_gallery'][$idx]['#cache']['keys']);
      }
    }
  }
}

But I recommend not doing this anymore. I'm now using view_mode_switch instead, which does the same thing with better code and with an UI (which basically means it is documented for editors)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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