56

So I have this Node:

object(Drupal\node\Entity\Node)[1862]
  protected 'values' => 
    array (size=17)
      'vid' => 
        array (size=1)
          'x-default' => string '7' (length=1)
      'langcode' => 
        array (size=1)
          'x-default' => 
            array (size=1)
              0 => 
                array (size=1)
                  'value' => string 'en' (length=2)
      ... (more fields)
      'field_image' => 
        array (size=1)
          'x-default' => 
            array (size=1)
              0 => 
                array (size=5)
                  'target_id' => string '1' (length=1)
                  'alt' => string '' (length=0)
                  'title' => string '' (length=0)
                  'width' => string '150' (length=3)
                  'height' => string '120' (length=3)

Now the field_image has an array with x-default and some basic image data. How do I show the image, or create a link to the image inside the Twig template?

9
  • Don't have time to check but maybe as simple as url(node.field_image.0.entity.uri) (relevant issue)
    – Clive
    Commented Nov 19, 2014 at 11:58
  • @Clive I tried this and gives me this error: Recoverable fatal error: Object of class Drupal\Core\Field\FieldItemList could not be converted to string so I tried it with this: url(node.field_image.0.entity.uri.value)but then it just tells me this: Twig_Error_Runtime: An exception has been thrown during the rendering of a template ("Route "public://image.png" does not exist.")
    – Rias
    Commented Nov 19, 2014 at 13:58
  • Errr...I would guess it needs to be done in a preprocess hook then, unless there's a Twig helper function to convert FieldItemLists into a string representation (which I can't find)
    – Clive
    Commented Nov 19, 2014 at 13:59
  • 1
    Oh I see, url() wants a route. How about url_from_path(node.field_image.0.entity.uri.value)?
    – Clive
    Commented Nov 19, 2014 at 14:00
  • Hmm url_from_path() seems to generate this: http://mywebsite.local/public%3A//image.png so it seems to be urlencoding and appending the exact value to the url
    – Rias
    Commented Nov 19, 2014 at 14:12

17 Answers 17

68

Here is an update version of for this answer after 8.0.x. This base on @joelpittet comment.

{{ file_url(node.field_image.entity.fileuri) }}
5
  • 2
    Please note, that you will get the url of the "unstyled" original image and not the image style specific url (e.g. thumbnail). Aside from VladimirM's answer there is no way to get the correct styled image url in twig. At least currently... Commented Aug 8, 2016 at 10:35
  • 3
    ... image styles are now available in Twig Tweak - drupal.org/project/twig_tweak
    – 4uk4
    Commented Mar 18, 2017 at 14:57
  • 1
    The File class has a url() method, so you can simply call entity.url() rather than passing entity.fileuri to file_url()
    – Kiee
    Commented Mar 11, 2019 at 15:25
  • 1
    I don't believe that is allowed - when I tried calling url() i got a twig error: Calling url method on a Drupal\file\Entity\File object is not allowed. Drupal docs say to use the file_url() method too: drupal.org/docs/8/theming/twig/…
    – kbrinner
    Commented Feb 4, 2020 at 23:05
  • You should use the file_url_generator service in a hook or maybe a custom field formatter. See drupal.org/node/2940031. file_create_url() and other methods are now deprecated. IMHO you shouldn't be using template files. Just use simple variables and avoid to drill down like this.
    – Tim
    Commented Feb 8, 2023 at 8:07
51

I don't know about Twig, but you get the file URI with $node->field_image->entity->getFileUri() in PHP, and the you need to call file_create_url() on that:

file_create_url($node->field_image->entity->getFileUri())

I don't know if that is possible in twig. If it's not possible, you can always calculate it in preprocess and add as a new variable.

1
  • 2
    We are trying to get file_create_url() into core but lack of interest has made the issue stale. drupal.org/node/2168231 Though if that got in it should be {{ file_url(node.field_image.entity.fileuri) }}
    – joelpittet
    Commented Nov 20, 2014 at 19:24
33

If someone needed a styled image:

$styled_image_url = ImageStyle::load('large')->buildUrl($node->field_image->entity->getFileUri());
2
  • 7
    This is a great answer. Note that in your .theme or .module file you'll want to add this to the top: use Drupal\image\Entity\ImageStyle;
    – mikeDOTexe
    Commented Oct 12, 2016 at 23:28
  • 2
    I ran into an issue with https, where Safari won't show the image as it uses the IP instead. You may want to add $relative = file_url_transform_relative($styled_image_url); to ensure it's relative. API here
    – mikeDOTexe
    Commented Oct 18, 2016 at 16:27
16

None of the above twig solutions worked for me (perhaps those worked for older 8.x versions but not for 8.5 version

{{ file_url(node.field_image['#items'].entity.uri.value) }}

NOTE: should be working for Drupal 8.5+

2
  • I think its bad that these kind of things get deprecated after a while. Upgrading Drupal should keep those working! This works for me in Drupal 8.6, thanks. Commented Mar 1, 2019 at 10:55
  • {{ file_url(node.field_image['#items'].entity.uri.value) }} Worked fine for me in my 8.8.2 version. Thanks Commented Mar 9, 2020 at 11:14
13

This is the way if you want to get the image URL with the associated image style for any image field in a twig template:

First install the Twig Tweak module

Then set the image URI as a variable. With the URI, you can use a twig tweaks pattern to get the path with whatever image style you want. See below:

{% set image_uri = content.field_feature_row_image['#items'].entity.uri.value %}

<img src="{{ image_uri|image_style('image1200x1103') }}"/>

Twig Tweak v2.4+ offers file_url filter to extract file URL from an entity.

<img src="{{ node.field_image|file_url }}"/>

And as of Twig Tweak v2.6 you can use file_uri filter in conjunction with image_style.

<img src="{{ node.field_image|file_uri|image_style('image1200x1103') }}"/>
9

What ended up working for me in D8 is:

$imageUrl = $node->get('field_image')->entity->uri->value;

Using kint($node->get('field_image')->entity) and looking through the array was very helpful

enter image description here

Then in my twig file I used:

<img class="top-article-image" src="{{ file_url(imageUrl) }}" />
1
  • what if there is not image inserted and we have set default value.
    – amol
    Commented Feb 10, 2017 at 5:40
7

So I've found out the answer with the help of Clive.

Getting the image URI in a template file is done using node.field_image.0.entity.uri.value. Provide a Twig extension for file_create_url(), closed as fixed on January, 2015, made possible to use file_url() in a template file.

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

I'm always using a helper function

  /**
   * Get the Image URI.
   *
   * @param \Drupal\Core\Entity\Entity $entity
   * @param $fieldName
   * @param bool $imageStyle
   * @return mixed
   */
  public function getImageUri(\Drupal\Core\Entity\Entity $entity, $fieldName, $imageStyle = FALSE) {
    $imageField = $entity->get($fieldName)->getValue();
    if (!empty($imageField[0]['target_id'])) {
      $file = File::load($imageField[0]['target_id']);
      if ($imageStyle) {
        return ImageStyle::load($imageStyle)->buildUrl($file->getFileUri());
      }

      // Original URI.
      return file_create_url($file->getFileUri());
    }
  }
2

you can get the url directly by using field_image.entity.url

2

I would highly recommend using the Twig Tweak module to get the URL from an image field in your twig template. Once you have installed the module you can then use various methods for extracting the URL from the image field. The following worked for me:

{{ node.field_main_image.0 | file_url }}

I set the background image of a <div> with the following:

<div style="background-image: url({{ node.field_banner_image.0 | file_url }})">
...
</div>

Make sure to add style for width and height or you won't see if it's working

IF THIS DOES NOT WORK FOR YOU, or if you want to learn all about the other great things twig tweak can do, reference this cheat sheet. This helpful document will save you a ton of time. I wish I knew about it earlier.

1

Gosh, it actually took my ages to find out why my resulting URLs didn't work. The all 404'ed. You need to create a derivate first if it doesn't already exist.

So for example when you add an image style later, after the original image was uploaded, then there's no styled image file yet (the image derivate). It needs to be created first.

Replace field_MYIMAGE and MYSTYLE as you need.

$original_image = $node->field_MYIMAGE->entity->getFileUri();
$style = \Drupal::entityTypeManager()->getStorage('image_style')->load('MYSTYLE');

$destination = $style->buildUri($original_image);
if (!file_exists($destination)) {
  $style->createDerivative($original_image, $destination);
}

$url = $style->buildUrl($original_image);

I wish this would happen automatically.

1

To Get image attribute like URI, alt, title etc use the syntax like below template wise

In node twig template

{{node.field_name.entity.fileuri}}

In field twig template

{{content.field_name.entity.fileuri}}

In other field twig template

{{element['#object'].field_name.entity.fileuri}}

Note: Also check twig_tweaks module cheat sheet for detail related to twig related issue.

1

This adds a drupal image style and the image alt test

{{ file_url(content.field_featured_image|field_target_entity.field_media_image.entity.uri.value| image_style('featured_image')) }}" alt="{{ content.field_featured_image|field_target_entity.field_media_image.alt }}
1

I'll probably thank me in the future:

content.field_name['#items'][0]|file_uri|image_style('style_name')

(with Twig Tweak)

0

somewhat related, here is what I used (thanks to all previous answers to get me there) to get an image file URL from a media entity's image field in twig:

{% set media_img_url = file_url(content.field_media_image.0['#item'].entity.uri.value) %}

now I can use this variable in my twig template

{{ media_img_url }}
0

You can use the url() method that is on the File class as a shortcut so:

{{ file_url(node.field_image.entity.fileuri) }}

can be shortened to:

{{ node.field_image.entity.url }}

This works in preprocess functions but triggers a Twig_Sandbox_SecurityError when called in a twig template.

If you receive Twig_Sandbox_SecurityError you can tell twig to allow url in your settings.php file as mentioned in this Stackoverflow post

See documentation on File::Url() https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/function/File%3A%3Aurl/8.6.x

0

Just noting: use file_uri, not file_url.

{{ node.field_image|file_uri|image_style('content_header') }}

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.