8

I'm implementing a node template that uses an image twice; once in a 'normal' way (i.e. using the image style defined in the field's display configuration for that view mode), and the other is as a css background-image property.

I need one of two things:

  1. (ideally) a way to get the URL for a different image style of the same image.

  2. a way to get the URL for the image field.

I'm struggling to use dump() and kint() to help myself to an answer. They both output far far too much (thanks to embedded links to "parent" etc.) and seem to not have the info I need. e.g. looking at dump(content.field_image) output the actual URL of the image is not there (so where does it come from such that it can be rendered with {{ content.field_image }}?!). kint() on the other hand dies completely if I pass an argument to it and the top-level version is again far too big to navigate. Debugging was soo much easier with phptemplate + xdebug. (Yes I know it's good that themers can't drop the database.)

There's an answer to (1) that implies you can't do it, but I don't understand why I can't get the existing URL in (2)?

10

You can get the image style url in a preprocess function and pass it to the node template. (in my case, I needed at the page level, I'm guessing this would still work for node)

Something like this, with "myimagefield" being the machine name for your image field, and "myimagestyle" being the machine name for your style, also make sure you include the Entity\ImageStyle.

use Drupal\image\Entity\ImageStyle;

/**
 * Implements hook_preprocess_page().
*/
function mytheme_preprocess_page(&$variables, $hook) {
  if ($variables['node']) {
    $node = $variables['node'];
    if($node->myimagefield[0]){
        $cover_image = $node->myimagefield[0]->entity->getFileUri();
        $image_url = ImageStyle::load('myimagestyle')->buildUrl($cover_image);
        $variables['my_image'] = $image_url;
    }
  }
}
  • 1
    the question says to pull the view mode from the field's display configuration. By doing the $image_url = ImageStyle::load('myimagestyle')->buildUrl($cover_image); how are you pulling the image style from the field's configuration? You simply added myimagestyle, but what if the same field is on multiple entities (e.g. nodes) where it requires different image styles? – usernameabc Mar 9 '18 at 16:54
12

The first part is already answered in the linked question, where there is the code how to do this. To answer the second part of the question, you can access the original image in the node object:

{{ file_url(node.field_image.entity.uri.value) }}

One remark about content:

In a node template the image field in content is not ready to be rendered. The field contains the configuration how it should be displayed and the field object which contains all raw data. Later this will be put together in the field, image-formatter and image templates. That is the reason you don't find the url you are looking for in content at this point.

In the node template you can use the fields on the top level of the content array, for example display the image field

{{ content.field_image }}

as configured in the view mode.

Edit:

There is a new filter in the module Twig Tweak. Now you can generate the image style url in twig directly from an uri or url of the original image:

{{ node.field_image.entity.uri.value | image_style('thumbnail') }} 
  • Thanks. So all the preprocess hooks get called when twig calls render e.g. at the point you go {{ content.field_image }} and not before? Also, I think the url i'll get from your suggestion is the original url - part 2 of my Q was asking for the url of the image style, as configures by the view mode. Is that possible? – artfulrobot Mar 15 '16 at 13:10
  • This only works for regular uploaded images and not for entity referenced images. How can this be made to work with entity referenced images? – paulcap1 Sep 22 '17 at 13:52
  • @paulcap1, don't know exactly what you mean, because an image field is a reference field (to a file entity). If you mean you have the image inside of a referenced entity, then you need .entity twice, first to get to the entity and second to the image. – 4k4 Sep 22 '17 at 15:24
  • 1
    @paulcap1, for example {{ node.field_ref.entity.field_image.entity.uri.value }} – 4k4 Sep 22 '17 at 15:31
  • @4k4. I am using the default Page content type. I have an entity referenced field called field_global_image. This uses the Image Bundle. The Bundles image field is called ""image" I tried it your way using {{ node.field_global_image.entity.image.entity.uri.value }} I also tried switching the fields like this {{ node.image.entity.field_global_image.entity.uri.value }} Neither worked. In my Answer in a seperate post, that is what worked for me. – paulcap1 Sep 23 '17 at 12:29
4

Install the Twig Tweak Module https://www.drupal.org/project/twig_tweak

And this module Twig Field https://www.drupal.org/project/twig_field_value

If you are using regular image upload field images use this in your node template:

<img src="{{ node.field_regular_image.entity.uri.value | image_style('thumbnail') }} " >

If you are using entity reference image use this:

<img src="{{ file_url(content.field_global_image|field_target_entity.image.entity.uri.value | image_style('thumbnail'))}} " >
  • Note that in the example about using referenced entities image after field_target_entity refers to the image field on the referenced entity. You might have to adjust it. – daniels Dec 11 '17 at 14:22
  • Thanks! The entity reference example can also be accomplished without the twig_field_value module by: file_url(node.field_image.entity.field_referenced_image.entity.uri.value | image_style('thumbnail')) – John Mar 29 '18 at 15:54

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.