1

I have a list of images, and I want access to both the direct path to the image, and the path with an image style applied to it available to a Twig template.

I'm grabbing the images in my .theme file like so.

$images = $node->get('field_image');

foreach($images as $image){
    $image_style =Drupal\image\Entity\ImageStyle::load('photos')->buildUrl($image->entity->getFileuri()),
    $image_path = file_create_url($image->entity->getFileuri()),    
}

I want to be able to access these attributes for each image by storing them in the $variables array.

I attempted to do so by using

foreach($images as $image){
    $image_style =Drupal\image\Entity\ImageStyle::load('photos')->buildUrl($image->entity->getFileuri()),
    $image_path = file_create_url($image->entity->getFileuri()),    
    $variables['photos'][]['image_style'] = $image_style;
    $variables['photos'][]['image_path'] = $image_path;
}

However that didn't work and I received errors. After that I figured that maybe I needed to supply a more explicit associative array so I tried

    $variables['photos'] = array();
    $photo_paths = array();
    foreach($images as $image){
        $photo_paths += [
            $i => [
                'image_style' => Drupal\image\Entity\ImageStyle::load('photos')->buildUrl($image->entity->getFileuri()),
                'image_path' => file_create_url($image->entity->getFileuri()),            
            ],
        ];

        $i += 1;
    }
    $variables['photos']= $photo_paths;

But then I receive the errors

User error: "image_style" is an invalid render array key in Drupal\Core\Render\Element::children() (line 97 of core/lib/Drupal/Core/Render/Element.php).

and

User error: "image_path" is an invalid render array key in Drupal\Core\Render\Element::children() (line 97 of core/lib/Drupal/Core/Render/Element.php).

These errors continue for each image. I'm guessing that $variables can't handle nested associative arrays? Is there a way I can use an associative array inside a Twig variable? Or is there another way to accomplish the same task or storing the path and image style for each individual image to be displayed in a for loop in Twig?

1
  • No, Twig won't try to render an array, it wouldn't know what to do with it. Drupal augments Twig such that any raw outputted array is treated as a render array, hence the error you're seeing when trying to render a non-render array. If you want to render the items in a non-render array, just use a traditional loop
    – Clive
    Mar 23, 2017 at 18:34

1 Answer 1

5

Twig doesn't understand what you put in the keys image_style and image_path. Twig can handle only arrays when the children are renderable. And this means they have to contain a '#type' or '#theme' key with a valid render element or theme name. For image styles use the theme image_style:

$variables['photos'] = [];
foreach ($images as $image) {
  $variables['photos'][] = [
    '#theme' => 'image_style',
    '#style_name' => 'photos',
    '#uri' => $image->entity->getFileUri(),
  ];
}

Then Twig can render the images like they're supposed to be rendered without the need for custom PHP code.

2
  • Ahh, so I need to supply it with actual render arrays?
    – Matt
    Mar 23, 2017 at 19:55
  • Yes, in your case you reach two goals at once, you can render the whole thing with {{ photos }} and you don't need to use php code to generate the image styles.
    – 4uk4
    Mar 23, 2017 at 20:02

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.