6

I want to allow the editor user to be able to select different responsive image styles to render an image field from a paragraph field. So I have defined another field where the user can select the responsive style they want.

The problem is that I can't apply that responsive style on the fly on the twig template, so I tried to altered the field or create the picture element and assign it to a variable I can access from the template in the hook_preprocess_field, but I can't access the url of the image in the variables. So I don't know how to carry on.

Is there a way to achieve this?

3 Answers 3

5

You don't need to swap the image, only the information how to render the image. And you can't do this in a field template. This is only possible in the paragraph template, where both fields are available:

function mytheme_preprocess_paragraph(&$variables) {
  if ($variables['paragraph']->hasField('field_image_style')) && isset($variables['content']['field_image']['0']) {
    $image_style = $variables['paragraph']->field_image_style->value;
    $variables['content']['field_image']['0']['#responsive_image_style_id'] = $image_style;
  }
}
3
  • Thank you @4k4!! That's exactly what I was looking for. I was trying to create another image to render following this example [vdmi.nl/blog/drupal-8-rendering-image-programmatically] (vdmi.nl/blog/drupal-8-rendering-image-programmatically) but this is much better. Also I didn't know how to do it because I didn't know how to access and iterate through the variables and functions for the objects inside $variables, I could see the content with the function dpm() but didn't know how to manipulate them. Is there a tutorial for this?
    – jmzea
    Sep 8, 2016 at 21:24
  • @4k4 Is there any way I can remove responsiveness from particular image. As in my case I have checkbox for editor on paragraph, if editor wants to render original image on all devices. Thanks Oct 5, 2016 at 13:54
  • 1
    You can get the paragraph object in the field template like so: $paragraph = $variables['element']['#object'];
    – ummdorian
    Oct 27, 2017 at 15:04
1

I have encountered this issue a handful of times and the best solution I found was using something like Zurb Interchange. This takes an image and swaps out the image src based on the screen size, dynamically.

I don't have a version for Drupal 8, but there is one for Drupal 7. It lets you select what image styles it should generate derivatives of, and their order (order important for media query). If you're interested in Zurb's plugin, perhaps you can port it to Drupal 8. I haven't had time or the opportunity to do so yet.

Though, as I understand it, it might not be necessary to do for Drupal 8, with the new stuff they added into 8.x: https://www.bluecoda.com/blog/using-responsive-images-drupal-8 - but I don't know if it swaps out the right image when the browser is resized by the user (something Interchange and plugins like it would do).

3
  • Hi @Kevin. The responsive images are working properly. What I need is to be able to change programmatically the responsive style selected in the configuration before rendering the image field.
    – jmzea
    Sep 8, 2016 at 18:28
  • I'm not sure I follow you there
    – Kevin
    Sep 8, 2016 at 18:30
  • The image is using a responsive image formatter. I have selected one of the responsive configurations, but I want to be able to select another configuration for that formatter when the field is rendered. I have defined a paragraph type that includes an image field and a field to select the responsive configuration, in that way I want to give the editor the capacity to select the image style he or she wants to render that image.
    – jmzea
    Sep 8, 2016 at 18:34
0

Beware of caching here folks. I started from the example above - thanks @4uk4 - then added a cache key removal line. Code below:

if ($variables['paragraph']->hasField('field_image_style') && isset($variables['paragraph']->field_image_style->entity)) {
    /** @var \Drupal\Core\Entity\Entity\EntityViewMode $viewMode */
    $viewMode = $variables['paragraph']->field_image_style->entity->field_view_mode_for_media->entity;
    // kint($viewMode);
    if ($viewMode != null) {
      $viewModeMachineName = $viewMode->id();
      //kint($viewModeMachineName);
      $viewModeMachineNameMediaPrefixRemove = str_replace("media.", "", $viewModeMachineName);
      //kint($viewModeMachineNameMediaPrefixRemove);
      //kint($variables['content']['field_image'][0]['#view_mode']);
      $variables['content']['field_image'][0]['#view_mode'] = $viewModeMachineNameMediaPrefixRemove;
      //  Need to tweak the cache keys - as we are getting a cached copy of the HTML for the responsive image style
      // Remove the cache keys for the image - rely on cache for the paragraph
      // See here: https://drupal.stackexchange.com/questions/311888/image-inside-paragraph-being-cached?noredirect=1#comment397045_311888
      unset($variables['content']['field_image'][0]['#cache']['keys']);
      //kint($variables['content']);
    }
  }

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.