0

I'm using responsive images (single img tag with srcset and sizes attributes). My content editors can manipulate the displayed size of the image with a custom field on a shared parent entity. Therefore I can't meaningfully use the sizes field from the responsive image module, because my editors can set the image size from 10% of a fixed container up to 100vw on per paragraph level.

I know how to preprocess the sizes attributes, but I don't know how to get to my shared parent entity, which holds the field determining the size of the image's parent container:

function template_preprocess_responsive_image(&$variables) {
  // pseudocode: don't know how to this
  $imageField = $variables['whatever'];
  $parentParagraph = $imageField->getParentMediaEntity()->getParentParagraphEntity();
}

My question is how do I get the parent paragraph entity as written above in pseudocode?

4
  • 1
    Could you check the value of $variables['#item']? It seems that the viewElements function of the field formatter adds $file->_referringItem to the render array, which I'd expect to be the parent entity. Sep 11, 2017 at 11:05
  • 1
    Yes, but this is another hook, template_preprocess_responsive_image_formatter() and you get the field item, which parent is the field and the grandparent is the paragraph.
    – 4uk4
    Sep 11, 2017 at 11:54
  • 1
    ... which you can get with this shortcut FieldItemBase::getEntity: $parentEntity = $imageField->getEntity();
    – 4uk4
    Sep 11, 2017 at 12:56
  • OK, seems I've had the wrong starting point with hook_preprocess_responsive_image(). Using hook_preprocess_responsive_image_formatter() and $entity = $variables['item']->getEntity(); I'm getting my media entity. Thanks for your help, I'll post an answer as soon as I have a working code.
    – Hudri
    Sep 11, 2017 at 13:21

1 Answer 1

6

Here is the the "real" code counterpart to the pseudecode from the question:

function THEMENAME_preprocess_responsive_image_formatter(array &$variables) {
  // get the imagefield's parent entity
  $fieldParent = $variables['item']->getEntity();

  // this line is only needed if using media entities (= entity references)
  // must disable entity view caching to work correctly
  $fieldParent = $fieldParent->_referringItem->getEntity();

  // get the image width from the custom field
  $myImgSizes = $fieldParent->get('field_image_size')->getString();
  // can't change attribute here => store it temporarily
  $variables['responsive_image']['#attributes']['data-overridesizes'] = $myImgSizes;
}

function THEMENAME_preprocess_responsive_image(array &$variables) {
  //override sizes attribute with my calculated value
  if (key_exists('data-overridesizes', $variables['img_element']['#attributes'])) {
    $variables['img_element']['#attributes']['sizes'] = $variables['img_element']['#attributes']['data-overridesizes'];
    unset($variables['img_element']['#attributes']['data-overridesizes']);
  }
}

If using media (=entity references) you also have to disable view cache for entites (see this question)

function MODULENAME_entity_view(&$build, $entity, $display, $view_mode) {
  if ($entity->getEntityTypeId() == 'media' && $entity->bundle() == 'image' && $view_mode == 'my_uncached_viewmode'){
    unset($build['#cache']['keys']);
  }
}
4
  • Answer is not yet fully correct, when using the same media on different paragraphs, I always get the first paragraph referencing the media, instead of the real parent.
    – Hudri
    Sep 12, 2017 at 11:27
  • Then you have to disable caching. You can do this for all media entities in the entity type definition by adding render_cache = FALSE or create a view mode and add to the config yaml file cache: false.
    – 4uk4
    Sep 15, 2017 at 7:25
  • Thanks, already found another question dealing with the cache issue, posted my final, working code
    – Hudri
    Sep 15, 2017 at 13:30
  • 2
    Thank you so much for this information! I didn't realize that _referringItem is unreliable due to caching. Turns out it was the source of my bug and setting cache: false within the config yaml file for my view mode fixed it. It appears there is an open issue for this on Drupal.org: drupal.org/project/drupal/issues/2908449 I agree with the issue creator that accessing parent entities is really important so I hope somebody works on it. It's way out of my league. Oct 3, 2018 at 0:34

Your Answer

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

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