Drupal 8: Get URI, Title, and Alt from Media Entity Reference Item

Over the last several days, I've railed in my head against the matroshka structure of Drupal entities. But when I tried to break out some helper functions, and when I realized what each of the different properties each entity had, I realized the complexities of entities were warranted. Life is complex, and thus Drupal is complex.

Entity references load a Media Entity, which load an Image from an image field, which load a File. The alt and title are on the Image, while the file URI is on the file.

The simplest thing, for me, is to create function that breaks them all apart, and another function that gets me an array of properties. Note, this only gets this information from the first image.

Here's the controlling function:

function mytheme_preprocess_node(&$variables) {
  if ($entity_ref_item = $node->get('field_primary_image')->first()) { // Start with the entity reference, get the first object
    $entities = mytheme_get_entities_from_media_entity($entity_ref_item->get('entity')->getTarget()); // Get the keyed array of entities
    if ($entities['file']) {
      // Set an array on the $variable
      $variables['img'] = mytheme_get_image_properties_array($entities['file'], $entities['img']); // Set the variables for the twig file
    }
  }
}

Here are the helper functions:

/**
 * Takes a media entity and returns a keyed array of entities: file, image, and media.
 *
 * @param $media_entity
 *
 * @return array containing a file, image, and media entity or null
 */
function mytheme_get_entities_from_media_entity($media_entity) {
  if ($img_entity_list = $media_entity->get('field_image')) {
    if ($img_entity = $img_entity_list->first()) {
      if ($file_entity = $img_entity->get('entity')->getTarget()) {
        return ['file' => $file_entity, 'img' => $img_entity, 'media' => $media_entity];
      }
    }
  }
  return NULL;
}
 
/**
 * Returns a keyed array of strings representing image src, alt, and title.
 *
 * @param $file_entity
 * @param $img_entity
 *
 * @return array keyed by image property
 */
function mytheme_get_image_properties_array($file_entity, $img_entity) {
  return [ 'src' => $file_entity->get('uri')->getString(),
    'alt' => $img_entity->get('alt')->getString(),
    'title' => $img_entity->get('title')->getString() ];
}

If you want to get a styled image from the file URI, after you have the result of mytheme_get_entities_from_media_entity you can do this:

use Drupal\image\Entity\ImageStyle;
$image_style_name = 'my_image_style';
ImageStyle::load($image_style_name)->buildUrl($entities['file']->get('uri')
                                                                ->first()
                                                                ->getString());

About the Author

Hi. My name is Jeremiah John. I'm a sf/f writer and activist.

I just completed a dystopian science fiction novel. I run a website which I created that connects farms with churches, mosques, and synagogues to buy fresh vegetables directly and distribute them on a sliding scale to those in need.

In 2003, I spent six months in prison for civil disobedience while working to close the School of the Americas, converting to Christianity, as one does, while I was in the clink.