By Jannis Hell


2015-12-27 20:00:38 8 Comments

I want to render an image as a background image via an inline style in twig. I created a field called bg_image and attached it to the standard plain page.

After fiddling around for hours I was able to get the Image URL in node.html.twig

{{ file_url(node.field_bg_image.0.entity.uri.value) }}

but I could not get it to work inside field--field-bg_image.html.twig

Can I get the node from there anyhow, so I can then get the image?

How can I get the image URL to use as inline style? I thought maybe I can pass a variable from field--field-bg_image.html.twig to image.html.twig and then just render

{{ uri }}

instead of

<img{{ attributes.addClass(classes) }} />

but I could not get it to pass the variable there unless I use includes

{% include 'image.html.twig' with {'image': image, 'isFromField': isFromField} %}

(isFromField is true, when it comes from the field--field-bg_image.html.twig) But that didn't work either. The Image was never rendered that way.

Would be very glad if you can help - my php knowledge is very basic. Thanks

5 comments

@Matt 2018-10-09 17:16:45

I've had some success using the Background Image Module when the use case allows for it. I use one of these code options when I need a customized DOM structure.

@Zyfraglover 2016-11-25 09:13:40

I'd do it another way. In your node preprocess function :

use Drupal\image\Entity\ImageStyle; // Don't forget this use.

function THEMENAME_preprocess_node__NODETYPE(&$variables){
    $node = $variables['node'];

    if(isset($node->get('field_image')->entity)){
        $image_style = 'large'; // Or whatever your image style's machine name is.
        $style = ImageStyle::load($style);
        $variables['image'] = $style->buildUrl($node->get('field_image')->entity->getFileUri()); // Generates file url.
    }
}

Then, in your template (node--NODETYPE.html.twig), just render the image that way :

{% if image %}
    <img src="{{ image }}" />
{% endif %}

Although, if you ever have to render a big amount of images, I'd advise you to load the styles in an array before you loop on each images. I'm saying that because I've ran into serious load time problems because I had to load over 300 images and for each image, I was loading the style individually instead of loading them all before, here's an example, same base as above :

use Drupal\image\Entity\ImageStyle; // Don't forget this use.

function THEMENAME_preprocess_node__NODETYPE(&$variables){
    $node = $variables['node'];

    if(isset(node->get('field_images')[0]->entity)){ // Notice how, this time, I check if the FIRST image is set (if it's true, then u'll allow the loop for at least 1 element)
        $images_styles = [
            'large' => ImageStyle::load('large'),
            'thumbnail' => ImageStyle::load('thumbnail')
        ];
        $count = 0;

        foreach($node->get('field_images') as $image){
            $variables['images'][$count]['large'] = $images_styles['large']->buildUrl($image->getFileUri());
            $variables['images'][$count]['thumbnail'] = $images_styles['thumbnail']->buildUrl($image->getFileUri());
            $count++;
        }
    }
}

Then again, in your template (node--NODETYPE.html.twig), just render the images that way :

{% if images %}
    <ul>
        {% for image in images %}
            <li>
                <img src="{{ image.large }}" /> // Large image url.
                <img src="{{ image.thumbnail }}" /> // Thumbnail image url.
            </li>   
        {% endfor %}
    </ul>
{% endif %}

I haven't really tested it and I'm getting all this out of my head so it might contain errors, feel free to warn me so I'll correct this :-).

@4k4 2015-12-28 08:47:36

The variable node is only preloaded in the node template (and the page template, if the url contains the node). Now if you want to access node fields in a field template you have to look in a different place:

field.html.twig:

{{ file_url(element['#object'].field_image.0.entity.uri.value) }}

element['#object'] is the parent entity in a field template and you can access any field from this entity (in your case the node).

If you want to access raw values from the actual field, it's better to follow the logic of the field twig and access the value inside of the items loop directly from the field item object #item:

{% for item in items %}
  {{ file_url(item.content['#item'].entity.uri.value) }}
{% endfor %}

Edit: Get the url of an image style

Install the module Twig Tweak and you can use the uri to get the url of an image style:

{% for item in items %}
  {{ item.content['#item'].entity.uri.value | image_style('thumbnail') }}
{% endfor %}

@Jannis Hell 2015-12-29 17:00:12

Great that works! Thank you. Is it also possible, to get it in a specific image style? (large or thumbnail)

@bennash 2016-07-26 13:58:03

I use this code in my .theme file:

function THEMENAME_preprocess_node(&$variables) {

  if ($variables['node']->field_image->entity) {
      $variables['image_url'] = $url = entity_load('image_style', 'medium')->buildUrl($variables['node']->field_image->entity->getFileUri());
  }
}

It could be improved. I'm checking for the image field, and loading its url with an image style.

Then in my node--page.html.twig file I have this:

{% if image_url is not empty %}
    <div class="featured-thumb">
        <img src="{{ image_url }}"/>
    </div>
{% endif %}

<div>{{ content.body|without('field_image') }}</div>

Again, that could use some improvement. thanks

@paulcap1 2017-09-22 11:30:35

This works for a regular image upload field. But it does not work for a entity reference image field.

@Jonasdk 2016-02-19 13:46:03

Just to mention that if you want to do the same in one of the new custom blocks this works:

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

@Alex 2016-05-05 14:24:48

This works for block field.

@Vadim Sudarikov 2018-03-13 16:24:18

And also this code works for image paragraph field in paragraph's twig template.

@Robb Davis 2018-04-03 16:09:09

Yes! Thanks. This works when you're trying to get the image url from the content image field on paragraph templates as well.

@Jignesh Rawal 2018-10-10 06:44:29

Does not work for views

Related Questions

Sponsored Content

1 Answered Questions

[SOLVED] Fetching(GET) image url with applied image styles using jsonapi module

1 Answered Questions

[SOLVED] How to set Class for a particular image style?

2 Answered Questions

[SOLVED] How to get image url in a twig file from a media entity

  • 2018-04-30 13:53:48
  • drupalhgy
  • 465 View
  • 0 Score
  • 2 Answer
  • Tags:   theming

3 Answered Questions

[SOLVED] Drupal 8: Rendeirng node fields in another region

  • 2017-06-27 02:06:01
  • Confused Drupaler
  • 2268 View
  • 5 Score
  • 3 Answer
  • Tags:   theming 8 entities

1 Answered Questions

2 Answered Questions

[SOLVED] How to get image with image style path to a twig template

  • 2017-04-13 08:10:26
  • Josh
  • 1463 View
  • 1 Score
  • 2 Answer
  • Tags:   theming

3 Answered Questions

[SOLVED] How to find image style URL from within twig template?

  • 2016-03-15 12:21:39
  • artfulrobot
  • 9678 View
  • 8 Score
  • 3 Answer
  • Tags:   theming 8 media

2 Answered Questions

[SOLVED] Get an image with style url from an URI in twig

  • 2016-01-02 12:12:47
  • Jannis Hell
  • 5534 View
  • 8 Score
  • 2 Answer
  • Tags:   theming 8 uri media

2 Answered Questions

1 Answered Questions

[SOLVED] In Drupal 8 how do I get the image path from a twig node template?

  • 2016-04-16 02:20:22
  • leif
  • 2039 View
  • 2 Score
  • 1 Answer
  • Tags:   theming 8

Sponsored Content